跨平台的C++动态库,适用于Linux和Windows。

29

我想编写一些跨平台的库代码。

我正在创建一个既包含静态库又包含动态库的库,大部分开发是在Linux上完成的。我已经在Linux上生成了静态和共享库,但现在想使用相同的源代码生成Windows版本的静态和动态库,分别为.lib.dll格式。

这是否可行?我有点担心,因为我注意到生成Windows的.dll文件需要在源代码中使用_dllspec或类似的东西。

我正在寻求最佳和最快的解决方案来编译我的代码以在Windows上运行。我不需要在Linux下进行编译;我很乐意直接在Windows下编译。此外,我正在使用两个外部库,它们是Boost和Xerces XML,我已经在我的Windows和Linux系统上安装了它们,所以希望它们不会成为问题。

我真正想要的是只有一个源代码副本,可以在Linux和Windows下编译,以生成特定于每个平台的库。我并不介意为了Windows或Linux而编辑我的代码,只要我有一个单一的源代码副本即可。


交叉编译通常指在一个平台上构建软件,以在另一个平台上运行。由于您说您想要能够在Linux和Windows上编译的源代码,那么您的问题实际上更多地涉及编写可移植的跨平台源代码库,而不是交叉编译。 - Nick Meyer
GIYF。实际上,在这种情况下,libtool是你的朋友... - Chris Lutz
在等待答案的同时,可以查看CMake:http://www.cmake.org/ - Pete
我对交叉编译或可移植代码都很满意,只要能达到相同的效果。当然,如果能够进行交叉编译会更理想,因为这可以节省时间,但是我没有选择的余地,无论哪种方法最好或最容易,我都会采用。此外,关于使用code::blocks IDE,我听说它有共享库模板,并且在Linux和Windows上都可用,有人知道它是否符合我的要求吗? - iQ.
3个回答

21
一般来说,你需要关注两个问题:
  1. 在 Windows 上,你的 DLL 必须通过 __declspec(dllexport) 显式地导出应该对外部可见的符号。
  2. 能够维护构建系统(理想情况下,不需要维护单独的 makefile 和 Microsoft Visual C++ 项目/解决方案)。
对于第一个问题,你需要了解 __declspec(dllexport)。在仅限 Windows 的项目中,通常会按照我在 这个问题 中描述的方式实现。你可以进一步扩展此方法,确保在为 Linux 构建时定义了导出符号(例如 MY_PROJECT_API),但展开为空。这样,你就可以根据需要将导出符号添加到你的代码中,仅影响 Windows 构建。
对于第二个问题,你可以调查一些跨平台构建系统。
如果您熟悉GNU工具集,您可能想调查libtool(也许与automake和autoconf一起使用)。 这些工具在Linux上被本地支持,并通过CygwinMinGW/MSYS在Windows上得到支持。MinGW还提供了交叉编译的选项,即在运行Linux时构建本机Windows二进制文件。 我发现在浏览自动化工具(包括libtool)方面有两个有用的资源:"Autobook"(特别是关于DLLs和Libtool的部分)和Alexandre Duret-Lutz的PowerPoint幻灯片。 正如其他人所提到的,CMake也是一个选择,但我不能代表它说话。

谢谢,我确实做了一些谷歌搜索,但猜测我搜索的不对,libtool听起来很有趣,或许像上面某人提到的那样使用cmake也是个好选择。由于我对Linux还比较新,这些工具并没有马上想起来。:p - iQ.
如果您使用Boost,可以使用boost/config.hh文件来定义宏以适当地导出符号到所有编译器和平台。 - Triskeldeian

13

你可以很容易地使用 #ifdef 来实现。在 Windows 平台上,即使是 64 位编译器, _WIN32 也应该被定义,因此可以编写类似以下的代码:

#ifdef _WIN32
#  define EXPORTIT __declspec( dllexport )
#else
#  define EXPORTIT
#endif

EXPORTIT int somefunction();

这对你应该没问题。


嗯,我考虑过那个,我会看看它会怎样,如果我在上面的工具上没有成功,可能会把这个作为我的最后手段。 - iQ.
@iQ:即使使用上述工具,您仍然需要执行此操作。它们不会为您处理导出,只是隐藏了不同平台上构建过程中的一些差异。 - Nick Meyer
是的,我想你是对的,我必须使用宏。我目前正在尝试查看CodeBlocks,我认为它可以自动为您定义.def文件,尽管我不知道那有多好或多坏。我需要进行一些实验。 - iQ.

8
也许最好加上extern "C" !!!, /* 文件 CMakeLists.txt */
 SET (LIB_TYPE SHARED)
 ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.h)

/* 文件 MyLibrary.h */

#if defined(_WIN32) || defined(__WIN32__)
#  if defined(MyLibrary_EXPORTS) // add by CMake 
#    define  MYLIB_EXPORT extern "C" __declspec(dllexport)
#  else
#    define  MYLIB_EXPORT extern "C" __declspec(dllimport)
#  endif // MyLibrary_EXPORTS
#elif defined(linux) || defined(__linux)
# define MYLIB_EXPORT
#endif

MYLIB_EXPORT inline int Function(int a) {
    return a;
}

@tstenner,你的意思是说你不喜欢当人们在打代码时随意编造自己的格式风格吗? :) - monkey0506

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接