封送结构(包含数组)作为返回值
Marshaling structure (that containes arrays) as return value
结构的C++代码如下:
typedef struct _a astruct;
struct _a {
BYTE fi, Sec, *D, *IIV, PV;
bool Visited;
};
以及使用它的功能:
astruct DoPDC(string *InitialData);
我想通过VB.NET使用这个函数(包含在DLL中),所以我为结构编写了以下代码:
<StructLayout(LayoutKind.Sequential)> _
Public Structure astruct
Dim fi As Byte
Dim Sec As Byte
Dim D As Byte()
Dim IIV As Byte()
Dim PV As Byte
<MarshalAs(UnmanagedType.Bool)> Dim Visited As Boolean
End Structure
以及函数声明:
<DllImport("astr.dll", EntryPoint:="DoPDC", BestFitMapping:=False, CallingConvention:=CallingConvention.Cdecl, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Ansi)> _
Public Function DoPDC(ByVal InitialData As String()) As <MarshalAs(UnmanagedType.Struct)> astruct
End Function
所以,我得到了一个悲惨的错误MarshalDirectiveError
,特别是Method's type signature is not PInvoke compatible.
,我以前从未见过这个错误,互联网上有很多不同的解决方案,但没有人有我的情况,我将一个字符串数组作为参数传递,返回一个包含更多数组的结构!
因此,我不知道哪里出了问题:参数、返回值、返回值内的数组还是全部加在一起?我很困惑。。。因此,我的问题是:如何修改VB.NET P/Invoke代码,使其正确工作?
(请注意,我不可能更改C++DLL,因为它不是我的,因此,我没有代码…)
问题出在D
和IIV
的定义中。您将它们声明为字节数组,但P/Invokemarshaller不知道这些数组有多大;指向传递长度的字节的指针并没有什么内在的东西。如果数组是可变长度的,那么P/Invokemarshaller是如何确定这个长度的?如果它们总是有一个已知的固定长度,那么你可以使用它,其中N
是数组的固定长度:
<MarshalAs(UnmanagedType.LPArray, SizeConst = N)>
如果返回的数组具有动态大小,并且您可以在函数返回后以某种方式确定它,那么将D
和IIV
声明为IntPtr
,并使用System.Runtime.InteropServices.Marshal
的方法提取数据。
如果指针指向它希望释放的函数分配的内存,则必须手动释放分配,这将涉及将这些指针发送回要释放的非托管函数。
这是一个非常糟糕的函数,必须使用pinvoke。.NET执法官没有机会,我们也没有。结构中数组的两个基本问题是:无法猜测它们有多长,也无法合理猜测谁拥有它们的内存以及应该如何释放内存。
您必须在Structure声明中将它们声明为IntPtr
。在执行更多操作之前,请编写一个重复调用的小测试程序。观察返回的IntPtr值。如果它们不同,那么你需要放弃,因为你无法释放内存,所以没有办法使用pinvoke。将需要一个C++/CLI包装程序。
如果它们没有不同,那么你就有机会了。使用Marshal.Copy()从IntPtrs复制数组。但是,您仍然需要知道要复制多少元素。如果您不知道,请致电C程序员。
顺便说一句,bool的[MarshalAs]是错误的,使其成为UnmanagedType.U1
- C++返回 Numpy 数组的 Python 扩展模块
- 如何从COM模块中的函数返回字符串数组?
- 从非托管 C# DLL 返回列表/数组
- 如何在C++中的单行中返回常量数组中的值
- 缩放和插值数组
- 如何使用 PHPCPP 传递对象数组,遍历每个对象并返回关联数组
- 返回 2D 数组(在 C# 和 C++ 中)
- 从我的对象返回静态数组
- 将 2D 数组作为函数参数,并返回 2D 数组作为函数的返回类型
- 从类型元组到通过调用模板函数返回的值数组
- C++返回自动数组
- 通过 Pybind11 返回 numpy 数组
- 采用OpenCV Mat<doube>并转换为12位值数组。
- 函数可以返回 2D 数组吗?
- 数组在函数中作为参数传递并被访问,那么为什么从函数返回后数组的值会被修改呢?
- 通过赋值运算符返回字符数组
- 传递指针数组并返回这些指针指向的值数组
- 面向对象C++帮助?出于某种原因,对象变量的输出返回数值数组位置而不是实际值
- sum 数组 Ascii,它接受字符串数组并返回该数组中所有字符串中所有字符的所有 ascii 值的总和
- 打印函数返回的数组指针的值(c++)