.net 解决错误C3821:托管类型或函数不能在非托管函数中使用
我正在编写一个C++/CLI层来处理一些互操作 本机API填充复杂结构,包括固定数组、联合、匿名结构等:.net 解决错误C3821:托管类型或函数不能在非托管函数中使用,.net,windows,c++-cli,interop,.net,Windows,C++ Cli,Interop,我正在编写一个C++/CLI层来处理一些互操作 本机API填充复杂结构,包括固定数组、联合、匿名结构等: typedef struct DECLSPEC_ALIGN(16) _FOO { union { BAR Bar; struct { POP Array[8]; DWORD More; }; }; } FOO, *PFOO; 我正试图将此数据结构转换为更“sane”.NET类,供
typedef struct DECLSPEC_ALIGN(16) _FOO {
union {
BAR Bar;
struct {
POP Array[8];
DWORD More;
};
};
} FOO, *PFOO;
我正试图将此数据结构转换为更“sane”.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;
}
这样做会产生错误:
错误2错误C3821:'无效测试::GetFoo(句柄)':托管类型或函数不能在非托管函数中使用
如果一个本地结构和一个新的不能存在于同一个函数中,人们怎么可能希望(甚至手动)在这两者之间封送数据
这里的许多Q/A涉及包装非托管类,这在这里似乎无关紧要
托管代码中不支持对齐的数据类型
这是真正的错误消息,不幸的是,它没有显示在错误列表窗口中。您只能在输出窗口中看到它。当编译器错误消息看起来很奇怪时,要记住一些事情
是的,这是准确的,托管代码不使用堆栈对齐保证来运行,而堆栈对齐保证是使结构对齐所必需的。32位代码以4的对齐方式运行,64位代码可以提供8。还不够好到16岁。编译器对此也无能为力,通常的堆栈指针操作在IL中不可用,这会破坏抖动生成的元数据,该元数据告诉垃圾收集器在遍历堆栈时查找对象引用的位置
所以,没有办法,你不能让它成为一个局部变量。你有选择,最直接的方法是分配:
#include <malloc.h>
....
FOO* value = (FOO*)_aligned_malloc(sizeof(FOO), __alignof(FOO));
try {
// etc...
}
finally {
_aligned_free(value);
}
#包括
....
FOO*value=(FOO*)\u aligned\u malloc(sizeof(FOO),\u alignof(FOO));
试一试{
//等等。。。
}
最后{
_无校准(值);
}
@HansPassant并非如此/clr
处于启用状态,我没有#pragma managed
或unmanaged
语句。试图使用/clr:pure
强制生成托管代码时出现错误Test::GetFoo无法在托管代码中生成:“托管代码中不支持对齐的数据类型”;使用/clr编译以生成混合图像
。我猜,DECLSPEC\u ALIGN
是什么在折磨我?虽然我会很惊讶,如果一个联盟被允许在托管代码附近的任何地方。好的,我明白了。请避免发布不可能的错误消息,GetFoo()不会返回void。@HansPassant对此表示抱歉,我显然是从一个更大的代码库开始工作的,并试图将问题提取到一个最小的示例,而不是实际创建一个最小的示例。我可以指望您,Hans回答我的.NET互操作问题。永远感谢你详尽的回答。