функция обратного вызова из неуправляемой DLL в VB .NET - PullRequest
0 голосов
/ 16 февраля 2009

Я пытаюсь использовать неуправляемую DLL в VB.NET. Пример исходного кода, поставляемого с dll, находится на VB6, и ниже моя попытка преобразовать его в. Когда DLL пытается сделать обратный вызов, я получаю исключение «Попытка чтения или записи в защищенной памяти». Меня действительно не волнует, что функция обратного вызова действительно вызывается. Мой код:

<DllImport("AlertMan.dll")> _
Public Shared Function AlertManC( _
    ByVal CallbackAddr As AlertManCallbackDel) As Long
End Function

Public Delegate Sub AlertManCallbackDel(ByVal data As Long)

Public Sub AlertManCallback(ByVal data As Long)       
End Sub

Public mydel As New AlertManCallbackDel(AddressOf AlertManCallback)
'protected memeory exception here
Dim IStat as Long = AlertManC(mydel) 

Оригинальный пример кода VB6:

Declare Function AlertManC _
    Lib "AlertMan.dll" _
    Alias "AlertManC" (ByVal CallbackAddr As Long) As Long

Private Sub AlertManCallback(ByVal data As Long)
End Sub

' calling code
Dim IStat As Long
IStat = AlertManC(AddressOf AlertManCallBack)

Оригинальный заголовок dll

typedef void TACBFUNC(char *);
int AlertManC(TACBFUNC *WriteCaller cHANDLEPARM);

Ответы [ 3 ]

2 голосов
/ 16 февраля 2009

Можете ли вы опубликовать оригинальное определение для AlertManC?

Хотя я предполагаю, что параметр данных функции обратного вызова на самом деле является целым числом против длинного. Я полагаю, что в VB6 были только 32 бита против VB.Net, где они 64-битные. Попробуйте это

   <DllImport("AlertMan.dll")> _
   Public Shared Function AlertManC(ByVal CallbackAddr As AlertManCallbackDel) As Long
   End Function

   Public Delegate Sub AlertManCallbackDel(ByVal data As IntPtr)


   Public Sub AlertManCallback(ByVal data As IntPtr)       
   End Sub

Редактировать

Я обновил код на основе подписи, которую вы опубликовали. Вы можете попробовать это?

0 голосов
/ 16 февраля 2009

Если соглашением о вызовах является cdecl, вы не можете сделать это непосредственно в C # или VB.NET.

Вам придется изменить IL делегата, чтобы он вел себя правильно.

Вы можете найти в CodeProject более подробную статью.

Обновление:

Наверное, не правильный ответ :) Но оставлю мой ответ.

0 голосов
/ 16 февраля 2009

Ваш обратный вызов должен выглядеть следующим образом:

Public Delegate Sub AlertManCallbackDel(ByRef data As Byte)

Причина в том, что вы передаете однобайтовое значение по ссылке.

Что касается объявления неуправляемой функции, оно должно выглядеть следующим образом:

<DllImport("AlertMan.dll")> _
Public Shared Function AlertManC( _
    ByVal CallbackAddr As AlertManCallbackDel) As Integer
End Function

Обратите внимание, что тип возвращаемого значения - целое число, которое в VB.NET является 32-разрядным значением. В VB6 Long был 32-битным значением, поэтому необходимо изменить VB.NET.

Определение обратного вызова также важно, чтобы понять, кстати.

...