Использование неуправляемой библиотеки - PullRequest
2 голосов
/ 11 октября 2010

Итак, в Visual Studio у меня есть решение с двумя проектами, первый из которых - управляемый код C ++, а второй - неуправляемая библиотека C ++ ( waffles ).Я хочу использовать классы из библиотеки в моем управляемом коде.

Если я просто добавлю 'include' GMacros.h '', то я получу 'не могу скомпилировать с ошибкой / clr'.Попытка обернуть включается в #pragma неуправляемым / управляемым, но, похоже, он не работает.

Могу ли я что-нибудь сделать, не редактируя код внешней библиотеки или не записывая какие-либо оболочки?

Ответы [ 3 ]

1 голос
/ 11 октября 2010

Неуправляемый код не может быть вызван напрямую в управляемом .NET.Вам необходимо добавить __declspec(dllexport) к объявлениям ваших функций, которые должны быть видны за пределами неуправляемой библиотеки:

public:
    void __declspec(dllexport) MyUnmanagedMethod();

И затем в вашем управляемом коде напишите простую оболочку, подобную этой:

public ref class Wrapper
{
public:
    [DllImport("MyUnmanagedLibrary.dll")]
    static extern void MyUnmanagedMethod();
}

Теперь вы можете вызывать Wrapper.MyUnmanagedMethod, как и любой другой статический метод из вашего управляемого кода.

1 голос
/ 11 октября 2010

Общее решение заключается в том, чтобы обернуть вызовы библиотеки в тонкие функции / классы-оболочки, заголовочные файлы которых вы можете включить в управляемый код.Не очень красиво, но доставит вас туда.

0 голосов
/ 12 октября 2010

P / Invoke с атрибутом DLLImport также требует, чтобы вы разбирались с маршалингом параметров функции, если она есть, типам CLR. Так, например, DWORD становится int, IN HANDLE может становиться IntPtr, LPDWORD становится out int, LPVOID обычно может маршалироваться как byte[] ... и т. Д. , Смотрите приличное резюме об этом здесь .

Пример из моего недавнего проекта, в котором мне пришлось взаимодействовать с DLL для старого цифрового блока вывода:

//This function's header in the DLL was:
//BOOL _stdcall fnPerformaxComSendRecv(IN HANDLE pHandle, IN LPVOID wBuffer, IN DWORD dwNumBytesToWrite, IN DWORD dwNumBytesToRead, OUT LPVOID rBuffer);
[DllImport("PerformaxCom.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool fnPerformaxComSendRecv(IntPtr pHandle, byte[] wBuffer, int dwNumBytesToWrite, int dwNumBytesToRead, byte[] rBuffer);
...