Jon*_*art 5 .net windows interop c++-cli
我正在编写一个C++/CLI层来处理一些互操作.
本机API填充了涉及固定数组,联合,匿名结构等的复杂结构:
typedef struct DECLSPEC_ALIGN(16) _FOO {
union {
BAR Bar;
struct {
POP Array[8];
DWORD More;
};
};
} FOO, *PFOO;
Run Code Online (Sandbox Code Playgroud)
我正在尝试将此数据结构转换为更"理智"的.NET类,供C#使用.问题是,我不能使用这个遗留结构,而gcnew我的新类在同一个函数中:
Foo^ Test::GetFoo(HANDLE h)
{
FOO foo; // Necessarily unmanaged
if (!::GetFoo(h, &foo))
throw gcnew Exception("GetFoo failed");
Foo^ result = gcnew Foo(); // Necessarily managed
// populate result
return result;
}
Run Code Online (Sandbox Code Playgroud)
这样做会给出错误:
错误2错误C3821:'void Test :: GetFoo(HANDLE)':托管类型或函数不能在非托管函数中使用
如果本机结构和a gcnew不能存在于同一个函数中,那么人们怎么能希望(甚至手动)对两者之间的数据进行编组?
这里有许多Q/A涉及包装非托管类,这似乎与此无关.
Han*_*ant 12
托管代码中不支持对齐的数据类型
这是真正的错误消息,遗憾的是它没有显示在错误列表窗口中.您只能在"输出"窗口中看到它.编译器错误消息看起来很奇怪时要记住一些事情.
是的,它是准确的,托管代码不会与堆栈对齐保证一起运行,以保证这种结构对齐.32位代码运行,对齐为4,64位代码可以提供8.不够好得到16.编译器也无法做到这一点,通常的堆栈指针操作在IL中不可用,这搞砸了抖动生成的元数据,告诉垃圾收集器在堆栈行走时对象的引用位置.
所以,没有办法,你不能把它变成局部变量.你有选择,最直接的方法是分配它:
#include <malloc.h>
....
FOO* value = (FOO*)_aligned_malloc(sizeof(FOO), __alignof(FOO));
try {
// etc...
}
finally {
_aligned_free(value);
}
Run Code Online (Sandbox Code Playgroud)