我有在旧版VB6代码中声明的此函数,并且我正在尝试将调用代码移至.NET。因此,我需要将以下内容转换为C#。
Private Declare Sub FooFunc "foo.dll" _
(ByRef A As Long, _
ByVal B As String, _
ByRef C As Long, _
ByRef D As Integer,)
我没有有关foo.dll的文档。我所拥有的只是VB6中的当前调用代码,该代码是由一个已经不在的人编写的:
Dim a as Long
Dim b as String
Dim c(2001) as Integer
Dim d(2001) as Long
c(0) = itemCount
d(0) = itemCount
For i = 1 To itemCount
c(i) = ...
Next
Call FooFunc(a, b, c(0), d(0))
DoSomethingWithD(d)
...
a
可能会被dll修改,所以我认为我需要out
关键字b
未修改c
是输入值的数组,未经修改d
是将获取输出值的预分配数组。令人困惑的是,第一个项目是传入的,但是我知道从VB6这样调用时,数组已被值填充我想在C#中需要类似以下内容的东西,但是在调用函数时得到AccessViolationException
。
[DllImport("foo.dll")]
public static extern void FooFunc(out int a, string b, int[] c, short[] d);
我已经尝试了其他一些变体,并在SO上查看了更多的解释,但是没有什么与VB6代码通过数组的奇怪方式完全匹配,而且我不知道这是否会使事情绊倒。也许这是一种使其像C样式的数组一样工作的方法?我认为,无论是谁制作的foo.dll,填写第一个都是奇怪的约定。
编辑1:
似乎FooFunc原本是要接收C数组的,但是C#甚至VB6都将传入SafeArrays,该数组在实际数组数据之前具有用于行距和界限的字节。如果是这样,则按引用传递第一个元素很有意义,因为FooFunc可以读取其余数据。
但是,由于非托管代码不能直接修改托管数组,因此我需要某种方式分配可以由非托管代码修改的非托管数组,并将指向第一个元素的指针作为参数传递。有办法吗?
答案 0 :(得分:1)
我认为您误读了代码。调用FooFunc不会传递数组,它会索引成两个数组,并传递对索引值的引用,以便可以对其进行更改。
[DllImport("foo.dll")]
public static extern void FooFunc(ref int a, string b, ref int c, ref short d);