我将一个代码片段分离到一个 DLL
中,因为它会经常更新,这样部署会更容易。
但是我对于可以在 DLL
中做什么和不能做什么有疑问。
- 我能否把
std:string
或者CString
传递给DLL
? - 我能否传递一个指向带有
std::string 成员
的struct
的指针,并在DLL
中填充它? DLL
能否返回在其中分配的结构体指针?它是否有效?我可以之后删除它吗?- 传递什么比较好,
std::String
还是Cstring
?
谢谢!
我将一个代码片段分离到一个 DLL
中,因为它会经常更新,这样部署会更容易。
但是我对于可以在 DLL
中做什么和不能做什么有疑问。
std:string
或者 CString
传递给 DLL
?std::string 成员
的 struct
的指针,并在 DLL
中填充它?DLL
能否返回在其中分配的结构体指针?它是否有效?我可以之后删除它吗?std::String
还是 Cstring
?谢谢!
紧密耦合的 DLL:该 DLL 使用与应用程序完全相同的编译器版本、打包和调用约定设置、库选项,并且两者都动态链接到运行时库(/MD
编译器选项)。这样可以传递对象,包括 STL 容器,从应用程序内部分配 DLL 对象,从另一个模块派生基类,几乎可以做任何不使用 DLL 的事情。缺点是您不能独立于主应用程序部署 DLL。两者必须一起构建。DLL 只是为了提高进程启动时间和工作集,因为应用程序在加载 DLL 之前就可以开始运行(使用 /delayload
链接器选项)。构建时间也比单个模块更快,特别是使用整体程序优化时。但是优化不会跨应用程序-DLL 边界进行。任何非微小改动仍然需要重建两者。
松散耦合:应用程序不依赖于 DLL 定义的对象的类布局。只使用高度兼容的数据类型:原始类型、指针、函数指针和由这些元素组成的用户定义类型。类继承自定义一个基类,定义接口并且没有数据成员和非虚函数(这意味着没有构造函数和不共享标准库对象,如 std::string
或 CString
)。所有分配和对象创建必须通过工厂函数完成。内存必须从分配它的模块释放。代码和数据是分开的。头文件明确说明了每个导出函数的调用约定和允许跨模块边界的每个结构的打包方式。优点是 DLL 和应用程序可以完全独立地更新。您可以使用新的运行时库、新的编译器版本甚至是完全不同的语言重新构建一个,而不必触及另一个。
我总是建议使用松散耦合的方法。
如果基于模板来传递DLL的任何内容,那么存在危险。编译器选项可能会影响对象的布局,而模板类无法限制为单个编译单元;其中一些将分发给调用模块。
对于字符串,我会传递const char *
(或const wchar_t *
或const TCHAR *
),并在接口的另一侧进行转换为std::string
或CString
。
std::string
,但它与应用程序中的std::string
不同。 你不能在应用程序和DLL之间传递std::string
,而是像Mark建议的那样传递char*
。 - Ben Voigtnamespace std
中类的定义仍然可能会发生变化(必须,因为C++标准委员会会更改要求),因此那些仍不能跨模块边界使用。 - Ben Voigt