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

时间:2013-06-22 15:19:17

标签: c++-cli

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

#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,但是,我将make_public用于非模板化的本机类型(例如nativeTypeA)并且它可以工作(即编译CallingAssembly时没有C4679)。我没有使用make_public,而是通过this post中建议的预处理程序指令将本机类声明为public并在本机头中使用了__declspec(dllexport)。还有必要有条件地排除“public”修饰符(通过CLR_ACCESS_MODIFIER),因为该类也包含在其他本机项目中:

#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> {
...
}

我还为nativeTypeB的基类(为了编译而必需)和它的typedef:

typedef public nativeTypeB<TT> MYASSEMBLY_LINKAGE nativeTypeB;

我不确定上面的行是否必要,但C4679仍然会出现。

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

我可以更改接口以接受非模板化类型,但我真的不想这样做,因为它会导致代码膨胀并且不那么优雅。 This帖子提到在我的本地课堂上正常使用“公共”应该有用。

有人可以帮忙吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

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

C ++ / CLI无助于此,而是提供了生成托管类型的功能,这些托管类型专门用于跨程序集共享。它还可以防止您通过共享本机类型来引发灾难(ODR违规)。您可以使用make_public pragma覆盖此值,但有限制(例如没有模板)。

共享本机类型的更好方法是通过COM风格的界面。