我正在使用MSVC,但我打算让我的库跨平台。 现在,我有类和函数的h和cpp文件。在MSVC中创建库就像将所有文件添加到标记为静态库或动态库的Visual C ++项目一样简单吗?或者我必须将我的课程和职能改为外部和诸如此类的东西吗?
由于
答案 0 :(得分:4)
对于DLL,您需要根据您是构建DLL还是导入DLL来指定
或__declspec(dllimport)
__declspec(dllimport)
。考虑这个例子:
__declspec(dllexport)
注意:我重新排序了“void”和“DLL_EXPORT”(以前称为DLL_FUNCTION),因为之前它已经混淆了。
当在DLL项目中包含标题时,函数将被标记为导出。当从另一个项目(没有BUILDING_DLL预处理器定义)中包含它时,它将被解释为DLL导入。这可以以完全相同的方式应用于类。在Linux(以及可能的其他类似平台)上,您可以安全地将DLL_FUNCTION定义为什么都不是,因为它不是必需的。
编辑,如果你希望你的函数可以从C调用,你显然也希望抛出__declspec(dllexport)
,以防止名称错位。
编辑2:在实践中,MSVC也会在构建DLL时生成静态库。任何使用DLL的项目都必须链接到库(它实际上不包含可执行代码;它仍然按照预期动态链接)以满足链接器。
答案 1 :(得分:1)
当然,除了下面描述的东西,我现在还没有记忆。您可以考虑查看大型跨平台开源项目,例如已经考虑过此类问题的wxWidgets。
静态lib(.a | .lib)就像制作对象(.o)文件的zip一样,这样你就可以将它们作为一个单元进行管理,当你编译其他程序时使用静态lib所有目标文件它需要将编译成。
在大多数情况下,您不需要再做任何其他事情,您也可以直接包含目标文件。
应考虑模块大小以及可能需要使用这些功能的次数 - 如果要在一个应用程序中使用来自多个模块的lib,请避免静态。
您需要为MSVC
指定多个标准类__declspec(dllexport)
__declspec(dllimport)
示例标题存根,使其足够独特,这样您就不会与其他库冲突
// MartinsHeader.h
#ifdef BUILDING_DLL_A
#define DLL_A_EXPIMP __declspec(dllexport)
#else
#define DLL_A_EXPIMP __declspec(dllimport)
#endif
void DLL_A_EXPIMP MyFunction();
class DLL_A_EXPIMP MyClass{};
如果没有显式实例化,公共接口中的模板类可能会引发警告,因此编译了所有模板代码。
您可能需要考虑使用PIMPL来最小化对类实现的外部可见更改。 (减少lib用户重新编译新lib的需要)
运行时在谁(de)分配什么方面变得很重要。
A)您可以坚持使用本机内存模型
B)您可以通过引入仅工厂分配和销毁方法来强制进行内存(de)分配,因此它全部由库执行。 (我不是很喜欢它,因为它使代码更难,但它可以使运行时问题更容易)
答案 2 :(得分:0)
静态或动态取决于您要加载它的方式。 如果它是静态的,您需要在构建应用程序时链接它。
对于这些功能,它又取决于你不想做什么。 如果它是一个插件你需要声明一些入口点 - > EXTERN 如果它是一个静态库,你只需要在使用它的应用程序构建中包含你的头文件。
这不是一个简单的问题,它实际上取决于你想做什么。