gpt4 book ai didi

c++-cli - 编译器错误 C2158 : make_public does not support native template types 的最佳解决方法

转载 作者:行者123 更新时间:2023-12-04 20:23:04 27 4
gpt4 key购买 nike

我有两个 c++/cli dll(即用/clr 编译),其中 A.dll 引用 B.dll。在程序集 B 中,我有一个方法 GetMgdClassB,我想从程序集 A 调用。这是程序集 B (B.cpp) 中的代码:

namespace B
{
public class NativeClassB
{
public:
NativeClassB();
// ...
};

public ref class MgdClassB
{
public:
static MgdClassB ^ GetMgdClassB(const std::vector<NativeClassB *> & vecNativeBs)
{
// ...
vecNativeBs;
return gcnew MgdClassB();
}
};
}

请注意,GetMgdClassB 方法采用 std::vector。在程序集 A 中,我尝试使用以下代码 (A.cpp) 调用此方法:
namespace B
{
class NativeClassB;
}

#pragma make_public(std::vector<B::NativeClassB *>)

namespace A
{
void Foo()
{
std::vector<B::NativeClassB *> vecNativeBs;
B::MgdClassB::GetMgdClassB(vecNativeBs);
}
}

当我编译 A.cpp 时,我收到以下错误:
error C2158: 'std::vector<_Ty>' : #pragma make_public directive is currently supported for native non-template types only

我想添加这个 pragma 的原因是因为默认情况下 native 类型是程序集私有(private)的。如果我删除编译指示,我会收到以下错误(如预期的那样):
error C3767: 'B::MgdClassB::GetMgdClassB': candidate function(s) not accessible

由于模板实例化类型 std::vector<B::NativeClassB *>对程序集是私有(private)的。

尝试的解决方案

1.使用void *,break类型安全:

换个方法, GetMgdClassB采取 void *并传递 std::vector<NativeClassB *> 的地址到方法。在 GetMgdClassB .然后我可以 static_cast传入的 void *std::vector<NativeClassB *> * .当然,这可行,但会破坏类型安全。

2.为NativeClassB创建一个Managed wrapper,传递一个托管容器

创建一个托管类,例如 ref class NativeClassBWrapper谁的唯一目的是保留对 native NativeClassB 的引用。更改 GetMgdClassB 以采用 NativeClassBWrappers 的托管容器(例如 List<NativeClassBWrapper ^> ^ )。这样做的缺点是必须在调用 GetMgdClassB 之前创建和填充新的托管容器,然后在托管类 B 中,我必须将其重新打包到 native 容器中 std::vector<NativeClassB *> (因为 B 中的代码处理这种类型。

目前,我倾向于使用解决方案 #1,因为 (a) 它不会引入任何性能问题,并且 (b) 我只会在少数情况下这样做。我不喜欢失去类型安全,但考虑到当前编译器使 native 模板实例化类型可见的能力不足,这似乎是合理的。

问题:

有更好的解决方法吗?

相关问题:

C++ CLI error C3767: candidate function(s) not accessible

最佳答案

我不知道有任何方法可以导出该类型。如果您必须拥有该函数签名,我会倾向于混合使用托管和 native 导出(使用 native 类型的托管函数无论如何都不能被其他语言使用),并且可能在调用 native 时使用延迟加载导出,因此您有机会捕获以通常的 .NET 方式查找程序集的错误。

但是您的特定函数可能存在问题,因为它在签名中同时使用托管类型和复杂的 native 类型。

通常,最佳实践是根本不跨 DLL 边界传递 native C++ 类,因为这会使您违反单一定义规则。

对于这种特殊情况,我的建议是制作一个实现 ICollection 的包装器。 .就像您的解决方案 #2 一样,这可以解决问题,而无需将所有元素实际复制到新的数据结构中。

关于c++-cli - 编译器错误 C2158 : make_public does not support native template types 的最佳解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4121249/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com