Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 解决错误C3821:托管类型或函数不能在非托管函数中使用_.net_Windows_C++ Cli_Interop - Fatal编程技术网

.net 解决错误C3821:托管类型或函数不能在非托管函数中使用

.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类,供

我正在编写一个C++/CLI层来处理一些互操作

本机API填充复杂结构,包括固定数组、联合、匿名结构等:

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互操作问题。永远感谢你详尽的回答。