C++ cli 导出C++/CLI本机类(C4679)

C++ cli 导出C++/CLI本机类(C4679),c++-cli,C++ Cli,我在C++/CLI程序集中(MyAssembly)有一个公共ref类,其中包含一个接受本机参数的公共静态方法 #pragma make_public(nativeTypeA) namespace namespaceA { public ref class MyClass : namespaceB::MyClass { public: static managedTypeA ^ MethodA(nativeTypeA param); st

我在C++/CLI程序集中(MyAssembly)有一个公共ref类,其中包含一个接受本机参数的公共静态方法

#pragma make_public(nativeTypeA)

namespace namespaceA
{ 
    public ref class MyClass : namespaceB::MyClass
    {
    public:
        static managedTypeA ^ MethodA(nativeTypeA param);
        static managedTypeB ^ MethodB(nativeTypeB param);
    }
}
我想将此方法公开给另一个C++/CLI程序集。托管程序集可以正常编译,但引用它的程序集(CallingAssembly)会为MethodB生成以下警告:

warning C4679: 'namespaceA::MyClass::MethodB' : could not import member
This diagnostic occurred while importing type 'namespaceA::MyClass ' from assembly 'MyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. 
我不能在nativeTypeB上使用make_public,因为它是模板化类的typedef,但是,我对非模板化的本机类型(例如nativeTypeA)使用make_public,并且它可以工作(即编译CallingAssembly时没有C4679)。我没有使用make_public,而是声明了本机类public,并通过post中建议的预处理器指令在本机头中使用了_declspec(dllexport)。还有必要有条件地排除“public”修饰符(通过CLR\u ACCESS\u修饰符),因为该类也包含在其他本机项目中:

#ifdef MANAGED
#define CLR_ACCESS_MODIFIER public 
#ifdef MYASSEMBLY_DEF
    #define MYASSEMBLY_LINKAGE __declspec(dllexport)
#else
    #define MYASSEMBLY_LINKAGE __declspec(dllimport)
#endif
#else
#define MYASSEMBLY_LINKAGE
#define CLR_ACCESS_MODIFIER
#endif

template<>
CLR_ACCESS_MODIFIER class MYASSEMBLY_LINKAGE nativeTypeB<TT> : public nativeTypeB_base<TT> {
...
}
#ifdef管理
#定义CLR\u访问\u修改器公共
#ifdef MYASSEMBLY_DEF
#定义MYASSEMBLY\u LINKAGE\u declspec(dllexport)
#否则
#定义MYASSEMBLY\u LINKAGE\u declspec(dllimport)
#恩迪夫
#否则
#定义MYASSEMBLY\u链接
#定义CLR\u访问\u修改器
#恩迪夫
模板
CLR_访问_修改器类MYASSEMBLY_链接nativeTypeB:公共nativeTypeB_基{
...
}
我还为nativeTypeB的基类(编译所必需的)及其typedef做了这项工作:

typedef public nativeTypeB<TT> MYASSEMBLY_LINKAGE nativeTypeB;
typedef公共nativeTypeB MYASSEMBLY\u链接nativeTypeB;
我不确定上面的行是否有必要,但C4679仍然以任何方式出现

我已经做了常规检查:托管预处理器指令是在两个项目中定义的;MYASSEMBLY_DEF在MYASSEMBLY中定义;我在CallingAssembly中添加了对MyAssembly的引用,并在其链接行中添加了MyAssembly.lib。项目构建顺序是正确的,没有缺少依赖项,但我仍然得到C4679

我可以将接口更改为接受非模板类型,但我真的不想这样做,因为这会导致代码膨胀,而且不那么优雅。波斯特提到在我的母语课堂上正常使用“public”应该是可行的

有人能帮忙吗


提前谢谢

跨越DLL边界传递本机类的对象从来都不是一个好主意,因为很容易违反一个定义规则

C++/CLI对此没有帮助,相反,它提供了生成托管类型的能力,这些类型是专门为跨程序集共享而设计的。它还通过共享本机类型防止您引发灾难(ODR冲突)。您可以使用
make_public
pragma覆盖此选项,但有一些限制(例如没有模板)


共享本机类型的更好方法是通过COM样式的接口。

这根本行不通,模板没有外部链接。使用一个简单的旧的包含。你能解释一下如何使用包含来完成这个任务吗?如果我只是#在调用者的头中包含MyClass.h,我会得到完全相同的C4679警告以及大量其他错误,例如类类型重新定义,因为两个程序集中都有同名类。我尝试将MethodB设置为私有,并从MyAssembly内的公共代理方法调用它,但这并没有删除警告,这似乎令人惊讶,因为调用方不应该具有私有方法的可见性。可能存在已同意的重复。我喜欢上面链接文章中的解决方案2。我可能通过一些重构来实现Hans建议的。这里也讨论了同样的话题:谢谢——很明显,我尝试的东西不受支持。我将修改接口以接受非模板类型。