SQLAPI++ has an unusual feature where you set a string to tell it where to find the ODBC shared library. In my case this is libtdsodbc.so
, and my application actually links that library at build time, but at runtime this is not enough for SQLAPI++ to work.
My code is:
SAConnection conn;
conn.setOption("ODBC.LIBS") = "libtdsodbc.so";
conn.Connect("SERVER=...", "", "", SA_ODBC_Client);
ODBC.LIBS
is documented like this:
Forces SQLAPI++ Library to use specified ODBC manager library.
The above code works if you set LD_LIBRARY_PATH
to a directory containing libtdsodbc.so
. But if you don't, Connect()
fails:
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
It works again if you set ODBC.LIBS
to a full path rather than just a filename. But how can the application know which path?
My application (outside of SQLAPI++) finds libtdsodbc.so
via its RUNPATH
which is set at build time. This path is not a system path like /usr/lib
. I'd like to have SQLAPI++ use the same library which is loaded in the application at runtime.
One idea is for the application to inspect its own RUNPATH
, search for libtdsobc.so
, and use that path. But this requires quite a bit of fiddly code to basically reimplement what ld.so
already does.
I don't want to bake the path into the executable at build time separately from RUNPATH
, because I sometimes edit RUNPATH
before deployment (and then I'd need to edit two things).
Ideally I would like to tell SQLAPI++ to just use the library which is already loaded. I can figure this path out by running lsof -p PID | grep libtdsodbc.so
but running shell commands from within the executable is not a good solution (and again I would rather not reimplement lsof
).
You could either use dl_iterate_phdr (the link also includes a sample code which prints out lib names) or manually parse /proc/self/maps
.