VB.net将结构体传递给非托管dll

3
我是一个有用的助手,能够翻译文本。
我正在将一些VB6代码迁移到VB.net,该代码包含一个结构,其中包含1d数组、2d数组和少量其他变量。
VB.net结构的一般概述如下。
Public Structure Test

    Dim a As Single
    Dim b As Single
    Dim c As Single
    <VBFixedArray(2)> Dim arr1() As Single
    <VBFixedArray(2, 2)> Dim mdarr1(,) As Single
    <VBFixedArray(4)> Dim arr2() As Byte
    <VBFixedArray(4)> Dim arr3() As Short
    <VBFixedArray(3, 2)> Dim mdarr2(,) As Integer

    Dim d As Integer
    Dim e As Decimal

End Structure

调用dll的声明如下

Public Declare Sub getState Lib "val.dll" (ByRef state As Test)

在这个网站的其他地方上,我意识到我们必须“编组”结构体,以使其与即将接受它的非托管代码兼容。
然而,当运行代码时,我仍然收到运行时错误,我不知道如何使用System.Runtime.InteropServices.Marshal类。
将此结构传递给dll的正确方法是什么?
编辑:
原始的VB6数据类型为
Public Type Test

    a As Single
    b As Single
    c As Single
    arr1(0 To 2) As Single
    mdarr1(0 To 2, 0 To 2) As Single
    arr2(0 To 4) As Byte
    arr3(0 To 4) As Integer
    mdarr2(0 To 3, 0 To 2) As Long

    d As Long
    e As Currency

End Type

你收到了哪些错误信息? - Chris Haas
内存错误,类似内存可能已损坏。 - Kevin Boyd
原始的VB6结构定义是什么?请记住,整数大小已从VB6中的2字节长度更改为.Net中的4字节长度。 - Mark Hall
1个回答

1

你是否有 val.dll 中的 getState 源代码?如果它是用 C 或 C++ 编写的,并且你有源代码或者只有头文件,你可以使用 P/Invoke Assistant 来自动生成 VB.Net 代码。

或者...(请发布原始的 VB6 结构!)

  • 在调用 getState 之前,你可能需要分配数组,例如 state.arr1 = {0.0, 0.0} 等。
  • Decimal 变量 e 可能会给你带来问题。在 VB6 中,这可能是一个 Currency 变量,而 Decimal 不是我记得的精确等价物。将其作为货币进行编组,VB.Net 会有一种方法。也许添加一个像这样的 attribute...

示例代码:

 Imports System.Runtime  
 Public Structure Test  
   ''blah blah

   <InteropServices.MarshalAs(InteropServices.UnmanagedType.Currency)> _  
   Dim e As Decimal  

   ''blah blah

是的,我有.h文件。它看起来对我来说是C语言。虽然我不太确定。抱歉我不太熟悉.net,但会查看p/invoke。原始VB6代码已发布!是的,VS2008升级向导确实在结构中添加了initialize()函数,该函数对必要的数组进行“redim”并将其初始化为所需长度。出于简洁起见,我没有发布那部分内容。 - Kevin Boyd
一定要通过P/Invoke助手运行.h文件并查看其内容。我发现e是一个Currency,所以我非常确定您需要像我的答案中那样将其编组为货币。你在调用initialize(),对吧? :) 您还可能需要添加一些属性来指示如何编组数组(它们需要作为平面数组进行编组)。 - MarkJ
扁平数组是指将二维数组作为一维数组进行编组。在这种情况下,一个数组(2,2)会变成一个数组(4),对吗? - Kevin Boyd
@Kevin 或许我不应该说“平坦数组”。我的意思是,结构体中的值应该按顺序直接存在内存中,没有指针或句柄之类的东西。如果你查看结构体的内存,你会看到4个字节的a,4个字节的b,4个字节的c,然后立即是4个字节的arr1(0),4个字节的arr1(1),4个字节的mdarr1(0,0),4个字节的mdarr1(0,1)等等。 - MarkJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接