VB6 DLL принимает обратный вызов как целое число, VB.NET требует делегата ссылочного типа - PullRequest
2 голосов
/ 21 декабря 2009

У меня проблема со сторонней библиотекой COM +, предназначенной для использования из VB6, где есть функция для установки обратного вызова для аппаратного события. Однако я использую VB.NET, и AddressOf теперь возвращает ссылочный тип вместо целочисленного, что означает, что функцию setCallback в библиотеке COM + DLL, очевидно, нельзя использовать.

Есть ли способ обойти эту проблему (у меня нет VB6 для разработки какой-либо оболочки), или мне нужно будет найти другую стороннюю DLL, чтобы заставить это работать? Для справки я пытаюсь получить доступ к ЖК-дисплею на клавиатуре Logitech G15 (v2).

Для справки, вот функция setCallback и сам прототип обратного вызова:

Public Sub setCallback(funcAddr As Integer)
Public Sub LCDbuttonPress(ByVal butStates As Integer)

1 Ответ

3 голосов
/ 21 декабря 2009

Я думаю, что если вы объявите свою функцию setCallback следующим образом:

Public Sub setCallback([MarshalAs(UnmanagedType.FunctionPtr)]funcAddr as function)

Я не парень VB, поэтому не знаю точного синтаксиса. Но основная идея здесь в том, что в VB.Net вы объявляете прототип как делегат, даже делегат правильного типа. Но затем вы используете атрибут MarshalAs, чтобы сказать маршаллингу, чтобы он обрабатывал его как указатель на функцию (фактически целое число) с другой стороны. Я делаю это в C #, чтобы передать обратные вызовы в код C ++, и это прекрасно работает.

Например, это в C #

public delegate int MyProgress(double dPercentComplete);
...
int WaitWithProgress([MarshalAs(UnmanagedType.FunctionPtr)]MyProgress pfn);

Появляется на стороне C ++ дома, как это

HRESULT __stdcall WaitWithProgress (long pfn, int * pRetVal);

Обратите внимание на комментарии. Фактическое решение этой проблемы оказалось Marshal.GetFunctionPointerForDelegate(), и будьте внимательны при чтении документации по этому вопросу. Если вы используете этот метод, вы обязаны убедиться, что делегат не является сборщиком мусора перед вами setCallback(NULL)

...