VB.net 将结构传递给非托管 dll
我正在将一些 VB6 代码迁移到 VB.net,该代码包含一个包含一维数组、二维数组和一些其他变量的结构.
I'm migrating some VB6 code to VB.net, the code contains a structure that contains 1d arrays, 2d arrays, and few other variables.
Vb.net 结构的大纲如下
The general outline of the Vb.net structure is as under
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的调用声明如下
The call to the dll is declared as under
Public Declare Sub getState Lib "val.dll" (ByRef state As Test)
在此站点的其他地方,我意识到我们必须编组"结构以使其与即将接受它的非托管代码兼容.
Elsewhere on this site I realized that we have to "marshal" the structure to allow it to be compatible with the unmanaged code that is about to accept it.
但是,我在运行代码时仍然收到运行时错误,我不知道如何使用 System.Runtime.InteropServices.Marshal
类.
However I still receiving runtime errors when running the code, I don't have any clue of how to use the System.Runtime.InteropServices.Marshal
class.
将此结构传递给 dll 的正确方法是什么?
What would be the correct way to pass this structure to the dll?
原来的VB6数据类型是
The original VB6 data type is
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
val.dll
中是否有 getState
的源代码?如果它是用 C 或 C++ 编写的,并且您有源代码甚至只是标题,则可以使用 P/Invoke Assistant 自动生成您的 VB.Net 代码.
Do you have the source code for getState
in the val.dll
? If it's written in C or C++, and you have the source code or even just the headers, you could use the P/Invoke Assistant to automatically generate your VB.Net code.
或者...(并且请发布原始的 VB6 结构!)
Alternatively... (and please do post the original VB6 structure!)
- 您可能需要在调用
getState
之前分配数组,例如state.arr1 = {0.0, 0.0}
等 -
Decimal
变量e
可能会给您带来问题.在 VB6 中,这可能是一个Currency
变量,据我所知,Decimal
并不是完全等效的.将有一种方法可以告诉 VB.Net 像货币一样编组它.也许添加一个 属性 像这样......
- You might need to allocate the arrays before calling
getState
, e.g.state.arr1 = {0.0, 0.0}
etc. - The
Decimal
variablee
could cause you a problem. In VB6 this was probably aCurrency
variable, andDecimal
is not an exact equivalent as far as I can remember. There will be a way to tell VB.Net to marshal it like a Currency. Perhaps adding an attribute like this...
示例代码:
Imports System.Runtime
Public Structure Test
''blah blah
<InteropServices.MarshalAs(InteropServices.UnmanagedType.Currency)> _
Dim e As Decimal
''blah blah