【发布时间】:2013-06-19 14:07:12
【问题描述】:
我在 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,但是,我将 make_public 用于非模板化的本机类型(例如 nativeTypeA)并且它可以工作(即编译 CallingAssembly 时没有 C4679)。正如this 帖子中所建议的那样,我没有使用make_public,而是将本机类声明为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 帖子提到在我的原生类中正常使用“public”应该可以工作。
谁能帮忙?
提前致谢!
【问题讨论】:
-
那是行不通的,模板没有外部链接。使用普通的旧#include。
-
您能否详细说明如何使用#include 来完成此任务?如果我只是在调用者的标题中#include MyClass.h,我会得到完全相同的 C4679 警告以及一系列其他错误,例如类类型重新定义,因为两个程序集中都有同名类。我尝试将 MethodB 设为私有并从 MyAssembly 中的公共代理方法调用它,但这并没有删除警告,考虑到调用者不应该看到私有方法,这似乎令人惊讶。
-
同意。我喜欢上面链接帖子中的解决方案 2。
-
我可能会通过一些重构来实现 Hans 的建议。这里讨论了相同的主题:stackoverflow.com/questions/12800262/…
标签: c++-cli