【问题标题】:SQLAPI++: Get path to shared library loaded by executableSQLAPI++:获取可执行文件加载的共享库的路径
【发布时间】:2017-04-20 08:22:08
【问题描述】:

SQLAPI++ 有一个不寻常的功能,您可以设置一个字符串来告诉它在哪里可以找到 ODBC 共享库。就我而言,这是libtdsodbc.so,我的应用程序实际上在构建时链接了该库,但在运行时这还不足以让 SQLAPI++ 工作。

我的代码是:

  SAConnection conn;
  conn.setOption("ODBC.LIBS") = "libtdsodbc.so";
  conn.Connect("SERVER=...", "", "", SA_ODBC_Client);

ODBC.LIBSdocumented 像这样:

强制 SQLAPI++ 库使用指定的 ODBC 管理器库。

如果您将LD_LIBRARY_PATH 设置为包含libtdsodbc.so 的目录,则上述代码有效。但如果你不这样做,Connect() 会失败:

libtdsodbc.so: cannot open shared object file: No such file or directory

DBMS API Library 'libtdsodbc.so' loading fails
This library is a part of DBMS client installation, not SQLAPI++
Make sure DBMS client is installed and
this required library is available for dynamic loading

Linux/Unix:
1) The directories in the user's LD_LIBRARY_PATH environment variable
2) The list of libraries cached in /etc/ld.so.cache
3) /usr/lib, followed by /lib

如果您将ODBC.LIBS 设置为完整路径而不仅仅是文件名,它会再次起作用。但是应用程序怎么知道是哪条路径呢?

我的应用程序(在 SQLAPI++ 之外)通过在构建时设置的 RUNPATH 找到 libtdsodbc.so。此路径不是/usr/lib 之类的系统路径。我想让 SQLAPI++ 使用在运行时加载到应用程序中的同一个库。

一个想法是应用程序到inspect its own RUNPATH,搜索libtdsobc.so,并使用该路径。但这需要相当多的繁琐代码才能从根本上重新实现 ld.so 已经完成的工作。

我不想在构建时将路径与RUNPATH 分开烘焙到可执行文件中,因为我有时会在部署之前编辑RUNPATH(然后我需要编辑两件事)。

理想情况下,我想告诉 SQLAPI++ 只使用已加载的库。我可以通过运行lsof -p PID | grep libtdsodbc.so 找出这条路径,但从可执行文件中运行 shell 命令并不是一个好的解决方案(我也不想重新实现lsof)。

【问题讨论】:

    标签: ld dynamic-linking sqlapi++ tdsodbc


    【解决方案1】:

    您可以使用dl_iterate_phdr(该链接还包括一个打印出库名称的示例代码)或手动解析/proc/self/maps

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2022-11-10
      • 2010-12-19
      • 2011-11-29
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多