【问题标题】:Two projects linking same SQLite library statically causes problems静态链接相同 SQLite 库的两个项目会导致问题
【发布时间】:2012-07-30 06:25:29
【问题描述】:

我有一个奇怪的问题。

我正在开发一个使用 C 编写的共享库和一个使用 C++ 编写的 GUI 应用程序。 GUI 应用程序使用共享库。这个共享库使用 SQLite 合并和静态链接。 GUI 也将 SQLite 用于某些配置目的。它也是静态链接的。他们都使用最新的 SQLite 版本。

我的共享库使用FTS4。我通过在编译共享库时提供编译时间选项来启用 FTS4。一切都适用于共享库。我在共享库代码库中的所有测试都通过了。

当我开始在 GUI 程序中使用它时会出现问题。我收到类似Unknown module FTS4 的错误。这很奇怪,因为我将它静态链接到我的共享库中,而这个 GUI 程序所做的只是动态链接到我的库。当我将 FTS 编译选项设置为 GUI 程序时,错误消失并且一切正常。

总之,

libfoo.so - 静态链接 SQLite 并打开 FTS4 选项 foo - 在没有任何特殊编译时选项的情况下静态链接 SQLIte。动态链接到libfoo

我不确定为什么会这样。任何帮助都会很棒!

【问题讨论】:

  • 没有编译/链接器错误。它在运行时加载不正确的函数版本。它总是从 foo 加载 SQLIte 函数。

标签: c++ c sqlite shared-libraries static-libraries


【解决方案1】:

听起来共享库中的所有 sqlite 函数都在导出。因此,当您加载共享对象时,所有这些函数都会解析到主应用程序,它还定义了符号名称的相同副本,但功能不同。

使用类似如下的地图文件编译共享对象可能会更好:

{
global:
  *;
local:
  sqlite3*;
};

将其放入名为foo.map的文件中,并在链接libfoo.so时(假设使用gcc)

gcc -Wl,--version-script=foo.map -o libfoo.so <dependent files>

这应该会导致使用 .so 中的内部符号,而不是主应用程序中定义的符号。

【讨论】:

  • 谢谢。这就说得通了。我会试一试。所以我认为这不会发生在 MSVC 上。因为 MSVC 不会导出所有函数。
  • 默认情况下,Windows 不会从 dll 中导出符号 - 您必须显式导出每个要使其可用的符号;另外 windows 将符号链接到库名称
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
相关资源
最近更新 更多