在VB.NET中修改C结构

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发送的结构?