代码之家  ›  专栏  ›  技术社区  ›  Matt Smith

编译器错误C2158的最佳解决方法:Make_Public不支持本机模板类型

  •  5
  • Matt Smith  · 技术社区  · 14 年前

    我有两个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);
        }
    }
    

    error C2158: 'std::vector<_Ty>' : #pragma make_public directive is currently supported for native non-template types only
    

    error C3767: 'B::MgdClassB::GetMgdClassB': candidate function(s) not accessible
    

    std::vector<B::NativeClassB *>

    GetMgdClassB void * std::vector<NativeClassB *> static_cast std::vector<NativeClassB *> *

    ref class NativeClassBWrapper List<NativeClassBWrapper ^> ^

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

    2 回复  |  直到 14 年前
        1
  •  2
  •   Ben Voigt    14 年前

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

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

    一般来说,最好的做法是不要在DLL边界上传递本机C++类,因为这会为您定义一个定义规则违规。

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

        2
  •  2
  •   Matt Smith    14 年前

    我在另一个论坛上收到了Mike Danes的解决方案:

    http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b43cca63-b0bf-451e-b8fe-74e9c618b8c4/

    基本上,解决方案是在程序集B中创建一个本地包装器(称为vectorofnativeb),它保存一个指向std::vector的指针或引用。导出vectorofnativeb并使其公开。将getmgdclassb方法更改为获取指针或引用vectorofnativeb。

    [在此处发布此内容以备将来参考,并查看此处是否有人对此解决方案发表任何评论]。