SQLAPI ++:获取可执行文件加载的共享库的路径

时间:2017-04-20 08:22:08

标签: ld dynamic-linking sqlapi++ tdsodbc

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

我的代码是:

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

ODBC.LIBS是这样的documented

  

强制SQLAPI ++ Library使用指定的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 ++之外)通过在构建时设置的libtdsodbc.so找到RUNPATH。此路径不是/usr/lib之类的系统路径。我想让SQLAPI ++使用在运行时加载到应用程序中的相同库。

一个想法是将应用程序发送到inspect its own RUNPATH,搜索libtdsobc.so,然后使用该路径。但这需要相当多的繁琐代码来基本上重新实现ld.so已经做过的事情。

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

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

1 个答案:

答案 0 :(得分:1)

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