我正在使用本机 DLL。我不确定,但我认为我不能使用 PInvoke decl,因为它不导出任何函数并且没有清单。DLL 附带一个头文件,说明如何使用它。头文件定义了无数的结构、枚举和一个类,使用工厂方法构建,该工厂方法通过 Windows 函数访问::GetProcAddress
(通过默默无闻的安全性)。此类包含我想在托管代码中使用的功能。
我已经成功地将这个类包装在一个 CLI ref 类中,并且可以在它上面调用一些简单的方法,也可以包装这些方法。
我正在经历将一些结构从头文件转换为托管结构的过程。例如,本机结构:
struct FooACL{
int action;
unsigned long from,to;
char comment[64];
int reserved[17];
};
变成托管结构:
[StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi)]
public value struct ManagedFooACL{
int action;
int from,to;
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 64)]
String^ comment;
[MarshalAs(UnmanagedType::ByValArray, SizeConst = 17)]
array<int>^ reserved;
};
据我所知,这应该使托管结构 blittable 吗?以及遵循类似模式或嵌套结构级别的任何其他结构。只要指定了一个布局并且没有一个 blittable 用 MarshalAs 装饰,那么整个结构会是 blittable 吗?
因此,我正在尝试查看是否有一种方法可以使用Marshal::Copy
或Marshal::PtrToStructure
将FooACL*
数组转换为array<ManagedFooACL>^
.
我从函数调用中获取 FooACL* 数组;我自己不分配。
int total;
FooACL* foos = unamagedClass->GetFooACLS(&total);
total
是获取返回数组大小的输入/输出。
到目前为止我设法做了什么,以及什么工作是:
ManagedFooACL first = static_cast<ManagedFooACL>(Marshal::PtrToStructure(IntPtr(&foos [0]), ManagedFooACL::typeid));
我无法理解的是为什么这不会:
array<ManagedFooACL>^ mfoos = gcnew array<ManagedFooACL>(total);
Marshal::PtrToStructure(IntPtr(&foos), mfoos);
这会引发:
System.ArgumentException was unhandled
Message=The specified structure must be blittable or have layout information.
Parameter name: structure
Source=mscorlib
ParamName=structure
有没有办法在一次调用中复制数组数据,还是我真的需要做一个 for 循环?所有这些编组功能似乎有点愚蠢。