Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用C+正确定义DLL接口+;11/14_C++_C++11_Dll_Stl_C++14 - Fatal编程技术网

C++ 使用C+正确定义DLL接口+;11/14

C++ 使用C+正确定义DLL接口+;11/14,c++,c++11,dll,stl,c++14,C++,C++11,Dll,Stl,C++14,我已经读过好几次了,在DLL边界之外传递STL对象(如vector和string)是不好的做法,因为不同的编译器版本可以为STL对象生成不同的代码。因此,您应该设计一个C风格的接口,而不是传递STL对象。但是,我仍然不清楚一些事情: 1。DLL的“边界”是什么? 这样说对吗,边界就是代码在DLL端编译的地方?如果我在DLL中定义一个.h文件(即编写工厂类),并在不同的项目中使用该头文件,会怎么样?该.h文件是在DLL边界之内还是之外?为什么 2。DLL中包含什么? 让我们假设我有一门课: cla

我已经读过好几次了,在DLL边界之外传递STL对象(如vector和string)是不好的做法,因为不同的编译器版本可以为STL对象生成不同的代码。因此,您应该设计一个C风格的接口,而不是传递STL对象。但是,我仍然不清楚一些事情:

1。DLL的“边界”是什么?

这样说对吗,边界就是代码在DLL端编译的地方?如果我在DLL中定义一个.h文件(即编写工厂类),并在不同的项目中使用该头文件,会怎么样?该.h文件是在DLL边界之内还是之外?为什么

2。DLL中包含什么?

让我们假设我有一门课:

class Foo
{
public:
    __declspec(dllexport) void f1(); //instantiates v1 inside function
private:
    unique_ptr<vector<int>> v1 = nullptr;
}

如何在现代C++ 11/14库中解决DLL STL问题?有什么现代的开源库我可以看一下吗?

为了回答问题2,当您将某个东西声明为
\uuuu declspec(dllexport)
时,您表示这是DLL接口的一部分-加载DLL的组件可以访问的东西。任何声明没有
\uuu declspec(dllexport)
的内容都应该存在于DLL中,但外部组件无法调用/使用它。

不幸的是,STL类型在编译器之间不一致。甚至不同版本的VisualStudio也存在差异

边界是编译代码的地方。如果库中的头文件中有实现,则用于编译EXE的编译器将编译代码。这可能非常糟糕,因为EXE中的代码认为是数据,而DLL中的代码认为是数据。(您需要注意这样的差异,特别是如果在结构定义中有#ifs,并且需要明确打包)

确保的唯一方法是定义所有您自己的类型(注意打包),而不是使用STL。这就是DLL库通常所做的

接口可以使用户动态链接到库。使用uu declspec(dllexport)需要静态链接;也就是说,EXE必须链接到编译DLL时生成的.lib才能访问所有函数。这意味着,除其他外,如果不重新编译EXE,就无法更新DLL(可能-在某些情况下,您可以不受影响,但这不是一个好主意)


通过动态链接,只要不更改接口,就可以更新DLL或向DLL添加功能,而无需重新链接EXE。EXE可以调用DLL上的LoadLibrary()和GetProcAddress()来访问一个返回接口的函数。包括作为参数传递的数据类型在内的所有其他内容都是接口(即仅包含纯虚拟函数)或简单结构。COM的基本层就是这样工作的。

On选项当然不是混合编译器版本,也不是为每个受支持的编译器构建单独的库。这可能是最简单的解决方案,我正在考虑这样做,因为确保一个可移植的DLL似乎是一个真正的斗争。一般来说,这对商业项目来说也是可以接受的吗?因此,基本上,所有代码都包含在.dll中,但只有用_declspec(dllexport)声明的代码是公共的,谢谢!
class IFoo
{
public:
    virtual ~IFoo() = 0 {};
    virtual void f1() = 0;
}
class Foo : public IFoo
{
public:
    void f1();
    //__declspec(dllexport) void f1(); //why use an interface if I can just declare the functions like this?
}