我在C ++ / CLI中有一个类 A ,它来自模板化基类 B 。 我有一些C#代码,其中包含 A 的实例,并希望在其上调用方法。 如果方法在 A 中实施,则一切正常。如果它在 B 中实现,那么事情会变得奇怪。
我敲了最简单的代码来演示我想要做的事情:
C ++ / CLI:
template<typename T>
public ref class B
{
public:
void Test(){}
};
public ref class A : public B<System::Int32>
{
};
C#:
A a = new A();
a.Test();
在此测试代码中,对Test()
的调用无法编译(我得到:“不包含'Test'的定义”)。如果我修改它以使Test()
静态(并在 A 而不是实例上调用它),我会得到相同的结果。如果这就是故事的结尾,我会在微软握拳并与之共处。
然而,在我的真实代码中,我有相当于Test()
的工作!
奇怪的是,它只适用于一个案例。如果我复制我的工作方法只是更改名称,则新方法无法再次访问。
为了排除从其他地方获取的命名,我尝试删除了工作方法。现在代码无法按预期构建。
我猜我所看到的仍然是一个小故障,而我正在尝试做的事情是不受支持的。但是由于我找不到任何可以排除它的参考文献,而且我看到了异常,我想知道我应该期待什么。
答案 0 :(得分:2)
在纯C ++中,模板化类方法只有在链接范围内实际使用时才会被实例化。我怀疑C ++ / CLI实现可能正在做相同的事情 - 如果它没有在C ++程序集中使用,则不会为Test()生成代码。
答案 1 :(得分:-1)
您的问题的答案实际上非常简单。编译混合程序集时--C ++ / CLI,编译器遵循一些规则来导出程序集外部的本机函数并为它们输出元数据。
其中之一是除非明确指定,否则本机方法不会从程序集中暴露出来。要显式指定通过元数据公开的本机方法,请使用#pragma make_public( Your Class Here )
。
另一个是模板函数不能暴露在程序集之外。因此,在您的情况下,您无法公开模板类。
但是在你的情况下,我几乎肯定你不需要模板类,而是一个绝对可以导出的通用类。
为什么需要模板?你了解模板&lt;&gt;之间的区别吗?和泛型&lt;&gt ;?一个是编译时单元,另一个是运行时。
尝试使用
generic<class T>
public ref class B
{
public:
void Test(){}
};
public ref class A : public B<System::Int32>
{
};