我正在尝试创建一个非托管C ++ DLL。在大多数情况下,我使用接口和工厂模式为用户跨DLL边界实例化复杂对象。
我的问题是关于可以在堆栈上分配的原始类类型。
例如,考虑下面的代码,我的库中有一个类和两个实用程序函数:
// Forward declaration for the PIMPL idiom
class SimpleData;
class Simple
{
public:
AWESOME_API Simple();
AWESOME_API Simple(const Simple& other);
AWESOME_API Simple& operator=(const Simple& other);
AWESOME_API ~Simple();
AWESOME_API void PublicFunction1(); // Public function with private implementation
AWESOME_API void PublicFunction2();
// ...
private:
void SecretFunction1();
void SecretFunction2();
// ...
private:
int m_Number;
SimpleData* m_Data;
// ... Other primitive data types ...
};
AWESOME_API static void DoSomethingWithSimple(Simple& simple);
AWESOME_API static Simple GiveMeASimple();
假设AWESOME_API
是__declspec(dllimport)
/ __declspec(dllexport)
属性的正确实现。
然后我可以使用这个库安全地在我的应用程序中执行以下操作,同时让用户可以自由地使用他们选择的任何编译器编译应用程序(只要它们都是32位应用程序)?
#include "Awesome/Simple.h"
int main(int argc, char* argv[])
{
Simple s0;
Simple s1(s0);
Simple* s2 = new Simple();
Simple s3 = GiveMeASimple();
DoSomethingWithSimple(s1);
DoSomethingWithSimple(*s2);
delete s2;
return 0;
}
如果没有,我如何跨DLL边界实现此功能?通过这样做,我对用户施加了哪些限制?
答案 0 :(得分:0)
不,这不安全。由于不同编译器的C ++ ABI不是必然兼容的,因此您无法在使用不同编译器编译的单元之间传递C ++对象。
答案 1 :(得分:0)
为了使其工作,有问题的编译器需要就类布局的外观达成二进制级别。我建议你阅读一下COM中实现的方法 - 这是定义一个抽象接口(基本上是一个vtbl,即函数指针列表),并确保编译器对此达成一致。
这就是说,例如,Visual Basic可以实例化并调用以任意语言实现的类的方法,前提是该语言支持COM绑定。
虽然COM是由Microsoft引入的,但这并不意味着您已将项目移植到使用他们的任何特定产品或库。您“只需”设置一些基本功能(QueryInterface,AddRef,Release等)。如果你是新手,这不是微不足道的,但它是一个有效的解决方案,这项技术值得学习。