Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在VB.NET中修改C结构_C_Vb.net_Dll_Interopservices - Fatal编程技术网

在VB.NET中修改C结构

在VB.NET中修改C结构,c,vb.net,dll,interopservices,C,Vb.net,Dll,Interopservices,我试图在我的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 {

我试图在我的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将vb.net委托发送到C DLL

Public Ext_Read As Del_Read = New Del_Read(AddressOf Read)
SendToDll(Marshal.GetFunctionPointerForDelegate(Ext_Read))
我的VB.NET函数声明为

Public Delegate Function Del_Read(ByVal lpReport As IntPtr) As Byte
 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发送的结构?

代码被黑客攻击致死,但它只需要Marshal.StructureToPtr(report,lpReport,False)。C函数指针的确切外观非常重要。您好,是的,我也尝试了Marshal.StructureToPtr(report,lpReport,False),但在运行时,当函数以相同的错误消息结束时,它也失败了。其他信息:试图读取或写入受保护内存。'这通常表明其他内存已损坏。”根据dll作者的说法,c函数指针是
typedef uint8_t(_stdcall*API_Read)(REPORT*)
API\u Read=NULL
报告
读取(&report)抱歉,伙计们,我已经修复了它,代码正如Hans Passant建议的那样好,问题是在Read()返回C DLL后立即调用的另一个错误的委托回调声明,很抱歉耽误了你们的时间。我投票结束这个问题,因为作者说问题是由缺陷引起的。请参阅作者的评论“抱歉,伙计们,我已经修复了它,代码正如Hans Passant所建议的那样好,问题在于另一个错误的委托回调声明,在Read()返回到C DLL后立即调用,很抱歉占用了您的时间。”–Messias 11月11日14日23:51