Mat*_*ith 5 compiler-errors c++-cli pragma
我有两个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();
}
};
}
Run Code Online (Sandbox Code Playgroud)
请注意,方法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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译A.cpp时,我收到以下错误:
error C2158: 'std::vector<_Ty>' : #pragma make_public directive is currently supported for native non-template types only
Run Code Online (Sandbox Code Playgroud)
我想添加此pragma的原因是因为默认情况下本机类型是程序集的私有.如果我删除该pragma,我会收到以下错误(如预期的那样):
error C3767: 'B::MgdClassB::GetMgdClassB': candidate function(s) not accessible
Run Code Online (Sandbox Code Playgroud)
因为模板实例化类型std::vector<B::NativeClassB *>对于程序集是私有的.
更改方法,GetMgdClassB获取void *并传递方法的地址std::vector<NativeClassB *>.在GetMgdClassB.然后我可以static_cast在传递void *给std::vector<NativeClassB *> *.当然,这有效,但打破了类型安全.
创建一个托管类,说明ref class NativeClassBWrapper谁的唯一目的是挂起对本机NativeClassB的引用.更改GetMgdClassB以获取NativeClassBWrappers的托管容器(例如List<NativeClassBWrapper ^> ^).这具有在调用GetMgdClassB之前必须创建和填充新托管容器的缺点,然后在托管类B中,我必须将其重新打包到本机容器中std::vector<NativeClassB *>(因为B中的代码处理此类型.
目前,我倾向于使用解决方案#1,因为(a)它没有引入任何性能问题,(b)我只会在少数情况下这样做.我不喜欢失去类型安全性,但鉴于当前编译器使本机模板实例化类型可见的能力不足,这似乎是合理的.
有更好的工作吗?
我不知道有什么方法可以导出该类型。如果您必须拥有该函数签名,我会倾向于混合使用托管和本机导出(使用本机类型的托管函数无论如何都不能被其他语言使用),并且可能在调用本机时使用延迟加载导出,以便您有机会捕获以通常的 .NET 方式查找程序集的错误。
但是您的特定函数可能会出现问题,因为它在签名中同时使用托管类型和复杂的本机类型。
一般来说,最佳实践是根本不跨 DLL 边界传递本机 C++ 类,因为这会导致违反“单一定义规则”。
对于这种特殊情况,我的建议是制作一个实现ICollection. 就像您的解决方案#2 一样,这可以解决问题,而无需实际将所有元素复制到新的数据结构中。
| 归档时间: |
|
| 查看次数: |
3131 次 |
| 最近记录: |