我有一个使用多个 C++ DLL 的非托管 Win32 C++ 应用程序。每个 DLL 都需要使用类 Foo - 定义和实现。
Foo.h 和 Foo.cpp 放在哪里,以便 DLL 链接并且最终不会在内存中复制代码?
这样做合理吗?
[编辑] 所有下面的答案和评论中有很多有用的信息 - 不仅仅是我标记为答案的那个。感谢大家的意见。
最佳答案
通过 DLL 以类的形式提供功能本身就很好。但是,您需要注意将接口(interface)与实现分开。谨慎程度取决于您的 DLL 将如何使用。对于保留在内部的玩具项目或实用程序,您可能甚至不需要考虑它。对于将由多个客户端在谁知道哪个编译器下使用的 DLL,您需要非常小心。
考虑:
class MyGizmo
{
public:
std::string get_name() const;
private:
std::string name_;
};
如果 MyGizmo
将被第 3 方使用,这个类会让你头疼不已。显然,私有(private)成员变量是一个问题,但是 get_name()
的返回类型也是一个问题。原因是因为 std::string
的实现细节是它定义的一部分。该标准规定了 std::string
的最低功能集,但编译器编写者可以自由地实现他们选择的功能。一个可能有一个名为 realloc()
的函数来处理内部重新分配,而另一个可能有一个名为 buy_node()
或其他名称的函数。数据成员也是如此。一个实现可能使用 3 个 size_t
和一个 char*
,而另一个可能使用 std::vector
。关键是你的编译器可能认为 std::string
是 n 字节并且有这样那样的成员,而另一个编译器(或者甚至是同一编译器的另一个补丁级别)可能认为它看起来完全不同.
一个解决方案是使用 interfaces .在您的 DLL 的公共(public) header 中,您声明一个抽象类来表示您的 DLL 提供的有用设施,以及创建该类的方法,例如:
DLL.H :
class MyGizmo
{
public:
static MyGizmo* Create();
virtual void get_name(char* buffer_alloc_by_caller, size_t size_of_buffer) const = 0;
virtual ~MyGizmo();
private:
MyGizmo(); // nobody can create this except myself
};
...然后在您的 DLL 内部,您定义一个实际实现 MyGizmo
的类:
mygizmo.cpp :
class MyConcreteGizmo : public MyGizmo
{
public:
void get_name(char* buf, size_t sz) const { /*...*/ }
~MyGizmo() { /*...*/ }
private:
std::string name_;
};
MyGizmo* MyGizmo::Create()
{
return new MyConcreteGizmo;
}
这可能看起来很痛苦,但事实确实如此。如果您的 DLL 将仅由一个编译器在内部使用,则可能没有理由去麻烦。但是,如果您的 DLL 将在内部或由外部客户端使用我的多个编译器,那么这样做可以避免以后出现的主要麻烦。
关于c++ - 如何在 DLL 之间共享类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2740573/