callback function from unmanaged dll in VB .NET

旧街凉风 提交于 2019-12-24 21:33:35

问题


I'm trying to use an unmanaged dll in VB.NET. The example source code provided with the dll is in VB6 and below is my attempt to convert it to .NET. When the dll tries to do a callback I get a "Attempted to read or write protected memory" exception. I really don't care about the callback function getting actually called. My code:

<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) 

Original VB6 example code:

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)

Original dll header

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

回答1:


Can you post the original native definiton for AlertManC?

My guess though is that the data parameter of the callback function is actually an Integer vs. a Long. In VB6 I believe Long's were actually only 32 bits vs. VB.Net where they are 64 bit. Try this

   <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

Edit

I updated the code based on the native signature you posted. Can you try this out?




回答2:


Your callback should look like this:

Public Delegate Sub AlertManCallbackDel(ByRef data As Byte)

The reason for this being that you are passing a single-byte value by reference.

As for the declaration of the unmanaged function, it should look like this:

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

Note that the return type is an Integer, which in VB.NET is a 32-bit value. In VB6, a Long was a 32-bit value, hence the need for a change in VB.NET.

The callback definition is important to get right as well, btw.




回答3:


If the callback's calling convention is cdecl, you cant do that directly in C# or VB.NET.

You will have to modify the IL of the delegate to behave correctly.

You can search on CodeProject for an in-depth article.

Update:

I guess not the correct answer :) But will leave my response.



来源:https://stackoverflow.com/questions/554091/callback-function-from-unmanaged-dll-in-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!