C++ 在不同的dll中将非托管模板类实例作为参数传递会导致编译失败
我有线程安全队列的非托管模板类:C++ 在不同的dll中将非托管模板类实例作为参数传递会导致编译失败,c++,templates,interop,c++-cli,C++,Templates,Interop,C++ Cli,我有线程安全队列的非托管模板类: template<class T> public class TSQueue {...} 模板 公共类队列{…} 和制片人级别: public ref class Producer { Producer(TSQueue<int>* Q) {...} }; 公共参考类生产者 { 生产者(TSQueue*Q){…} }; 生产者的使用方式如下: Producer^ p =
template<class T>
public class TSQueue {...}
模板
公共类队列{…}
和制片人级别:
public ref class Producer
{
Producer(TSQueue<int>* Q) {...}
};
公共参考类生产者
{
生产者(TSQueue*Q){…}
};
生产者的使用方式如下:
Producer^ p = gcnew Producer(new TSQueue<int>());
Producer^p=gcnewproducer(newtsqueue());
两者都在一个C++/CLI DLL Producer.DLL中定义
当Producer被实例化并在此DLL中提供TSQueue Error 23 error C2664: 'Producer(TSQueue<int>*)' : cannot convert parameter 1 from 'TSQueue<T> *' to 'TSQueue<int> *'
错误23错误C2664:“生产者(TSQueue*)”:无法将参数1从“TSQueue*”转换为“TSQueue*”
好像编译器无法确定我提供给生产者构造函数的Q类型一样
我已经添加了对Producer.DLL的引用
有人知道如何克服这个问题吗。IMO,添加对DLL的引用是不够的,因为我们这里讨论的是w/“本机”模板,而不是w/泛型。
请确保您的另一个DLL对
TSQueue
的标头具有#include
指令。您需要在两个库中都包含TSQueue的完整定义。不要让它成为接口的一部分,只在内部使用它。如果它需要成为API的一部分,请遵循Hans Passant的建议:使其成为通用的,或者更好,使用适当的框架实现。正如Hans Passant所说:
比较肯定的是,这里有一个类型标识问题,因为有一个本地C++模板跨越了模块边界。这通常是C++中的一个臭名昭著的问题,模板没有外部链接。在C++/CLI中,使用泛型很容易解决这个问题,如果需要线程安全,您应该从.NET队列类ConcurrentQueue中为TSQueue添加一个替换项
但是泛型不能用于非托管类型,因此我使用的是特定于类型的非托管容器类。。并且标头必须包含
TSQueue
模板的源代码才能工作。我想,只是模板的页眉不够,我没有提到,但是我已经包含了定义的标题和模板类的实现。这里确实有一个类型标识问题,因为有一个本机C++模板跨越了一个模块边界。这通常是C++中的一个臭名昭著的问题,模板没有外部链接。在C++/CLI中,使用泛型很容易解决这个问题,如果需要线程安全,您应该从.NET队列类ConcurrentQueue中为TSQueue添加一个替换项。感谢您提供的信息,我不熟悉这个约束。问题是我需要非托管类型的模板容器,这就是为什么我不能使用泛型。