16

我试图在我的 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 发送的结构?

4

0 回答 0