以跨平台方式导出共享库符号?

发布于 2024-08-06 19:29:12 字数 131 浏览 7 评论 0原文

是否有一种跨平台方法可以有选择地从构建共享库的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悲凉≈ 2024-08-13 19:29:12

当然,完全不可以,因为工具链不一样。

但人们就是这么做的。复杂之处在于,在 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 where
the function is defined and __declspec(dllimport) in the locations
in 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文