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*时,编译和执行没有问题

但是,当我尝试在另一个C++/CLI dll中用TSQueue*实例化Producer时,我遇到了以下编译器错误:

    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添加一个替换项。感谢您提供的信息,我不熟悉这个约束。问题是我需要非托管类型的模板容器,这就是为什么我不能使用泛型。