Mes*_*ias 16 c vb.net dll interopservices
我正试图在我的VB.NET应用程序中使用C编码的其他人的DLL.我的VB.NET应用程序发送一些指向DLL和DLL的回调指针,然后回调我的VB.NET应用程序内的函数.
DLL在VB.NET中调用一个函数并传递一个C结构的指针.我的VB.NET应用程序必须修改struct值,因此DLL可以使用新的struct值.我不能修改DLL的代码,因为它是别人的DLL.
typedef struct {
uint8_t index;
uint8_t value;
uint8_t leds[4];
struct {
int8_t x;
int8_t y;
int8_t z;
} input[10];
} REPORT;
Run Code Online (Sandbox Code Playgroud)
我的VB.NET结构定义是
<StructLayout(LayoutKind.Sequential)> _
Public Structure INPUTS
Public x As SByte
Public y As SByte
Public z As SByte
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure REPORT
Public index As Byte
Public value As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)>
Public leds() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)>
Public input() As INPUTS
Sub New(numleds As Integer, numinputs As Integer)
ReDim Me.leds(numleds)
ReDim Me.input(numinputs)
End Sub
End Structure
Run Code Online (Sandbox Code Playgroud)
我的VB.NET委托被声明为
Public Delegate Function Del_Read(ByVal lpReport As IntPtr) As Byte
Run Code Online (Sandbox Code Playgroud)
vb.net将vb.net委托发送给C DLL
Public Ext_Read As Del_Read = New Del_Read(AddressOf Read)
SendToDll(Marshal.GetFunctionPointerForDelegate(Ext_Read))
Run Code Online (Sandbox Code Playgroud)
我的VB.NET函数声明为
Public Function Read(ByVal lpReport As IntPtr) As Byte
Dim report As New REPORT(3, 9)
report.index = 0
report.value = 5
report.input(0).x = 90
report.input(0).y = 0
report.input(0).z = 0
report.input(1).x = 180
report.input(1).y = 0
report.input(1).z = 0
Dim size As Integer = Marshal.SizeOf(report)
Dim ptrMem As IntPtr = Marshal.AllocCoTaskMem(size)
Marshal.StructureToPtr(report, ptrMem, False)
Dim bytes As Byte() = New Byte(size - 1) {}
Marshal.Copy(ptrMem, bytes, 0, bytes.Length)
Marshal.FreeCoTaskMem(ptrMem)
Marshal.Copy(bytes, 0, lpReport, size)
Return 1
End Function
Run Code Online (Sandbox Code Playgroud)
当函数结束时,我得到以下错误,没有别的.
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Run Code Online (Sandbox Code Playgroud)
我尝试过不同的代码,Marshal.AllocHGlobal或者将函数声明为
Public Function Read(ByRef localReport As REPORT) As Byte
Run Code Online (Sandbox Code Playgroud)
即使代码编译得很好,错误也是因为Marshal.StructureToPtr以某种方式,因为如果我将代码更改为如下所示,我没有错误,DLL获得新值.唯一的问题是,我要计算手动偏移report.input(0),report.input(1)等等.
Public Function Read(ByVal lpReport As IntPtr) As Byte
Dim report As New REPORT(3, 9)
report.index = 0
report.value = 5
Dim size As Integer = Marshal.SizeOf(report)
Dim bytes As Byte() = New Byte(size - 1) {}
bytes(0) = report.index
bytes(1) = report.value
Marshal.Copy(bytes, 0, lpReport, size)
Return 1
End Function
Run Code Online (Sandbox Code Playgroud)
任何想法为什么代码失败?或者更简单的方法来修改从DLL发送的结构?