C # DllImport возвращает тип TCHAR? - PullRequest
0 голосов
/ 20 марта 2009

У меня есть функция c ++ со следующей подписью

TCHAR *DXGetErrorDescription9(HRESULT hr);

У меня есть

[DllImport("dxerr9.dll",EntryPoint="GetDXErrorString9")]
    static public extern string GetDXErrorString9(int DXError);

Как мне добавить строку в TCHAR *? Спасибо

1 Ответ

1 голос
/ 20 марта 2009

После небольшого копания выясняется, что подпрограммы с ошибками directx поставляются не как dll, а как библиотеки, которые вы статически связываете с исполняемым файлом. Я должен был рассчитать это, основываясь на размере dxerr9.lib (это 5M, намного больше, чем у всех других библиотек-заглушек).

Итак, чтобы заставить это работать, я сделал следующее:

  1. Создайте "обертку" нативную dll, которая обернет все функции lib обработки ошибок. Поскольку их всего 3 (DXGetErrorDescription, DXGetERrorString и DXTrace), это не такая уж большая проблема.
  2. .NET должен вызывать функции-оболочки.

Вы можете сделать это в Visual Studio, создав проект Win32 (измените настройки приложения, чтобы он был dll и экспортировал символы). Я назвал min "DirectXErrWrapper".

Внутри проекта оболочки добавьте проход для DXGetErrorDescription. Я назвал мой DXGetErrDescPassThrough ():

extern "C" {

DIRECTXERRWRAPPER_API TCHAR * DXGetErrDescPassThrough(HRESULT hr)
{
    return (TCHAR *)DXGetErrorDescription(hr);
}

}

Внешний блок "C" важен (имеет отношение к разборке имен C ++). Этот проект должен будет #include "dxerr.h" и статически связать dxerr.lib, поэтому вам придется добавить директиву sdk include dir в ваш путь включения и директиве directx sdk lib в ваш путь lib.

Затем ваш управляемый код импортирует вызов из вашей dll-оболочки:

[DllImport("DirectXErrWrapper.dll", CharSet=CharSet.Unicode)]
static public extern string DXGetErrDescPassThrough(int DXError);

В собственных проектах 2005 года по умолчанию используется Юникод, поэтому DllImport необходимо было указать Юникод. И, наконец, позвоните из управляемого кода с помощью:

Debug.WriteLine("DXGettErrDescPassThrough=" + DXGetErrDescPassThrough(0));

В этом случае вызов выводит «Функция успешно завершена» на устройство отладки, поскольку 0 является успешным.

(предыдущий пост следует)

Это похоже на одну из функций DirectX (C ++, а не C # AFAIK). Я уверен, что он поставляется с версиями Unicode и ANSI. TCHAR будет отображаться в Unicode при компиляции в Unicode (T является мнемоникой для типа; Unicode в Unicode, многобайтовый набор символов в MBC, ANSI в противном случае). Обычно вы можете использовать CharSet = CharSet.Auto, но если это вызывает проблемы с совместимостью (например, вам нужно использовать строки ANSI из-за какой-то структуры, которую вы уже перенесли, требуется), вы можете использовать то, что соответствует вашему проекту (либо Charset Юникод, если вы все юникод или Charset.Ansi) у вас не должно возникнуть проблем с маршалингом в строку C #. Вам может потребоваться оформить его как [OUT], хотя возвращаемое значение может быть неявно OUT. Я также желаю, чтобы DirectX поставлялся с TLB в соответствии со стандартным соглашением [out, retval]!
...