以跨平台方式导出共享库符号?
是否有一种跨平台方法可以有选择地从构建共享库的 C 项目中导出某些函数和结构?
我想以一种不需要特定构建系统的方式进行(可见性应该在代码中定义,例如作为宏),并且以 GCC 和 MSVC 都能理解的方式进行。
谢谢。
Is there a cross platform way to selectively export certain functions and structs from a C project which builds a shared library?
I want to do in a way that does not require a specific build system (the visibility should be defined in the code, eg as a macro), and in a way which both GCC and MSVC can understand.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当然,完全不可以,因为工具链不一样。
但人们就是这么做的。复杂之处在于,在 Windows 中,您需要
特别标记您想要从中导出的函数的声明
库中位置带有
__declspec(dllexport)
的 DLL该函数在以下位置定义和
__declspec(dllimport)
在引用函数的客户端代码中。因为标准
C 实践在单个头文件中只有一个声明,这
意味着你通常需要做一些宏观工作才能有一个
在两个位置都有效的前缀。好像每个项目
为此选择自己的标准。
在 Unix 方面,您根本不需要标记导出,这很好。
这是因为默认情况下会导出每个非静态函数,
这不太好。通常你可以摆脱这个只要
您的非公共/非静态符号具有合理的前缀,这就是
大多数项目似乎都是如此。如果您需要更好地控制您的
导出的符号,您可以在 GNU 中使用 Solaris 风格的“映射文件”
链接器的 --version-script (solaris 下的 -M)参数用于显式定义应出现哪些符号
在外部命名空间中。
平台之间还存在一些问题,例如
每个库的全局命名空间的工作原理和处理
启动/关闭代码。基本上,这是一个不可能的老鼠巢穴
在这么短的帖子中理智地解释了,但只要你小心
你的库包含简单的函数,而你的命名空间不包含
污染,你应该不会有太大的麻烦。多看看一些
流行的跨平台共享库(例如 Qt、Glib/Gtk+ 等)
与 msys 等一起分发)以获取指导。
Strictly no, of course, because the toolchains aren't the same.
But people do this. The complexities are that in windows, you need to
specifically tag the declarations of functions you want exported from
a DLL with
__declspec(dllexport)
in the location in the library wherethe function is defined and
__declspec(dllimport)
in the locationsin client code where the funciton is referenced. Because standard
C practice has only one declaration in a single header file, this
means that you generally need to do some macro work to have a single
prefix that works in both locations. It seems like every project
picks its own standard for this.
On the Unix side, you don't need to tag exports at all, which is nice.
This is because every non-static function is exported by default,
which is not so nice. Often you can get away with this as long as
your non-public/non-static symbols have sane prefixes, which is what
most projects seem to do. If you need finer control over your
exported symbols, you can use a Solaris-style "mapfile" with the GNU
linker's --version-script (-M under solaris) argument to define explicitly which symbols should appear
in the external namespace.
There are a few more gotchas between the platforms, like the way the
per-library global namespace works and the handling of
startup/shutdown code. Basically, it's a rats nest that can't be
sanely explained in a post this short, but as long as you're careful
that your library contains simple functions and your namespace doesn't
pollute, you shouldn't have much trouble. Look to some of the more
popular cross-platform shared libraries (e.g. Qt, Glib/Gtk+, anything
distributed with msys, etc...) for guidance.