我试图在我的 VB.NET 应用程序中使用别人用 C 编码的 DLL。我的 VB.NET 应用程序向 DLL 发送一些回调指针,然后 DLL 回调我的 VB.NET 应用程序内的函数。
DLL 在 VB.NET 中调用一个函数并传递一个 C 结构的指针。我的 VB.NET 应用程序必须修改结构值,因此 DLL 可以使用新的结构值。我不能修改 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;
我的 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
我的 VB.NET 委托被声明为
Public Delegate Function Del_Read(ByVal lpReport As IntPtr) As Byte
vb.net 将 vb.net 委托发送到 C DLL
Public Ext_Read As Del_Read = New Del_Read(AddressOf Read)
SendToDll(Marshal.GetFunctionPointerForDelegate(Ext_Read))
我的 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
当函数结束时我得到以下错误,没有别的。
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
我尝试了不同的代码,例如Marshal.AllocHGlobal
或将函数声明为
Public Function Read(ByRef localReport As REPORT) As Byte
即使代码编译得很好,错误是由于 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
任何想法为什么代码失败?或者更简单的方法来修改从 DLL 发送的结构?