Clear Filters
Clear Filters

Clib is unable to load an interface library

18 views (last 30 days)
Matt
Matt on 26 Apr 2023
Commented: Javier Ros on 20 Jun 2023
Hello,
I have a c++ shared library that I want to call from matlab using clib. Unfortunately when doing so clim seems to be unable to find some dependent libraries. Seems an easy problem but can't find my way around, so here are the details :
  • I compiled with g++ a force_camera_restart.so library that I want to call from matlab.
  • This library contains (for now) a unique c++ fonction force_camera_restart that look lke this
void force_camera_restart(void);
  • force_camera_restart.so depends on a couple of libraries in /opt/EVT/eSDK/lib
  • Those libraries are in the rpath so I think I should not have to put their path on LD_LIBRARY_PATH. Nevertheless i still do it, just in case, with the method from here
Here how is how I build an interface to my force_camera_restart.so :
%% 01 before launching matlab I type this in a prompt
unset LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/EVT/eSDK/lib:$LD_LIBRARY_PAT % should not be usefull but can't hurt
export LD_LIBRARY_PATH=/home/iscat/test:$LD_LIBRARY_PATH % where my force_camera_restart.so is
export LD_LIBRARY_PATH=/home/iscat/test/force_camera_restart:$LD_LIBRARY_PATH % where my interface.so will go
% Lauching matlab from the prompt (not sudo)
%% 02 checking LD_LIBRARY_PATH and PATH
LD_LIBRARY_PATH = getenv('LD_LIBRARY_PATH');
split(LD_LIBRARY_PATH,':') % checking : OK
% Adding .so to the path (I don't know why but I saw this in a exemple)
loc =['/opt/EVT/eSDK/include:',... % contains the .h of the following lib
'/opt/EVT/eSDK/lib:',...
'/opt/EVT/eSDK/genicam/bin/CLProtocol/Test/Linux64_x64:',... % eSDK/lib librairies depends on librairies here so ... why not adding it ?
'/home/iscat/test:',...
'/home/iscat/test/force_camera_restart:'];
path = getenv('PATH');
setenv('PATH', [loc path]);
path = getenv('PATH');
split(path,':') % checking : OK
%% 03 Generate Definition & build interface
headerFiles = '/home/iscat/test/force_camera_restart.h';
includePath = '/opt/EVT/eSDK/include';
% putting in a cell format all the lib path :
libPath = '/opt/EVT/eSDK/lib/*.so*';
libraries_dir = dir(libPath);
for ii=1:length(libraries_dir)
libraries_path{ii} = [libraries_dir(ii).folder ,'/', libraries_dir(ii).name ];
end
libraries_path{end+1} = '/home/iscat/test/libforce_camera_restart.so';
clibgen.generateLibraryDefinition(headerFiles, "IncludePath", includePath, ...
'Libraries', libraries_path, 'OutputFolder', pwd, 'PackageName', 'force_camera_restart',...
'OverwriteExistingDefinitionFiles',true,'verbose', true);
% Build definition
build(defineforce_camera_restart)
% add to path
addpath('/home/iscat/test/force_camera_restart')
% test
clib.force_camera_restartInterface.force_camera_restart
clib.force_camera_restart.force_camera_restart
% I get :
% Unable to load interface library:
% '/home/iscat/test/force_camera_restart/force_camera_restartInterface.so'.
% Reason: The specified module could not be found.
% Ensure the C++ dependent libraries for the interface library are added to
% run-time path.
Why is matlab not finding my libraries ?
To help find which are missing I tried to use ldd as explained here and here (in the comments) :
system('ldd libforce_camera_restart.so')
% All librairies are well defined
system('ldd force_camera_restartInterface.so')
% All librairies are well defined as well
And finally about the lib libforce_camera_restart.so itself, it works : I can write a cpp code calling this lib and execute the function force_camera_restart, it works fine.
Thank you !

Answers (2)

Suman Sahu
Suman Sahu on 5 Jun 2023
Edited: Suman Sahu on 5 Jun 2023
Hello Matt,
It is possible that the runtime libraries required by your shared library have not been properly resolved by MATLAB when attempting to load the library. Here are a few steps you can follow to troubleshoot the issue:
1. Check the library dependencies: Use the ldd command to check the list of dependencies for your shared library. For example, if your shared library is called force_camera_restart.so, run the following command in the terminal:
ldd /home/iscat/test/libforce_camera_restart.so
2. Check the library search path: Check the LD_LIBRARY_PATH variable to ensure that it includes the correct paths to the libraries required by your shared library. You can do this by running the following command in MATLAB:
disp(getenv('LD_LIBRARY_PATH'));
3. Specify library search path explicitly: You can try specifying the library search path explicitly by adding the following line in your MATLAB script:
setenv('LD_LIBRARY_PATH', '/path/to/dependency/libraries');
%Replace "/path/to/dependency/libraries" with the directory path that contains the required libraries.
4. Run MATLAB with elevated privileges: If the library search path and dependencies are correct, try running MATLAB with elevated privileges (using sudo) to see if this resolves the issue.
5. You need to import the library before you can call its functions:
import clib.force_camera_restart.* %will import everything from your library.
Hope that helps.
  1 Comment
Matt
Matt on 6 Jun 2023
Edited: Matt on 6 Jun 2023
Hi Suman,
1. Using the ldd command I see that all dependencies are resolved. (I see all of the dependencies memory adress as you can see).
>> system(' ldd /home/iscat/test/libforce_camera_restart.so ' )
linux-vdso.so.1 (0x00007ffc97347000)
libstdc++.so.6 => /usr/local/MATLAB/R2022a/sys/os/glnxa64/libstdc++.so.6 (0x00007f794723e000)
libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007f7947033000)
libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007f7946ee4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f794741b000)
libgcc_s.so.1 => /usr/local/MATLAB/R2022a/sys/os/glnxa64/libgcc_s.so.1 (0x00007f7946eca000)
2. The libraires are on the rpath and on the LD_LIBRARY_PATH, I checked as you can see in the code I posted.
3. I tryed as you showned to add the librairires explicitely to the LD_LIBRARY_PATH, it does not change the error message.
4. I get an error message about my matlab licence when I sudo matlab. edit : i managed to run matlan as root but I still get the same error.
5. Good to know ! I missed this step. So I can import the library, no warning or error, but when I call the lib I still get the same error message.
Two additional remarks :
  • During the clibgen.generateLibraryDefinition() step I get the following warning
Warning: Some C++ language constructs in the files for generating interface file are not
supported and not imported.
Deleted file '/home/iscat/test/defineforce_camera_restart.mlx'.
Deleted file '/home/iscat/test/defineforce_camera_restart.m'.
C++ compiler set to 'g++'.
Definition file defineforce_camera_restart.mlx contains definitions for 1 constructs supported by MATLAB.
- 1 construct(s) are fully defined.
To build the interface, call build(defineforce_camera_restart).
When I have a look at the defineforce_camera_restart.mlx definition generated I see no commented area. So I came to the conclusion that despite the warning everything is fine, but maybe not ?
  • I would be expecting the ldd function to show more dependencies, and especially those located in '/opt/EVT/eSDK/lib' that I know to be necessary. If I write a cpp program, called test_lib, that calls the unique function from my lib force_camera_restart, and check for test_lib dependendies ( ldd test_lib ) I find way more dependencies for it then for libforce_camera_restart.so

Sign in to comment.


Javier Ros
Javier Ros on 20 Jun 2023
HI!.
I'm in a similar situation, in,linux as well.
I have a library libginac_matlab.so that I compile myself that interfaces a system wide library (/usr/lib/libginac)
Everything goes OK, but same error when trying to call the functions defined in my library.
If I do system('ldd ./ginac_matlab/ginac_matlabInterface.so') or even
system('ldd ./ginac_matlab/libginac_matlab.so')
Everithing seems OK.
But if I add the modifier -d
>> system('ldd -d ./ginac_matlab/ginac_matlabInterface.so')
linux-vdso.so.1 (0x00007ffd98598000)
libginac_matlab.so => /home/jros/Sync/Programming_Tricks/ginac_matlab/libginac_matlab.so (0x00007f1ccb839000)
libMatlabDataArray.so => /home/jros/MATLAB/R2023a/bin/glnxa64/libMatlabDataArray.so (0x00007f1ccb81b000)
libstdc++.so.6 => /home/jros/MATLAB/R2023a/sys/os/glnxa64/libstdc++.so.6 (0x00007f1ccb645000)
libgcc_s.so.1 => /home/jros/MATLAB/R2023a/sys/os/glnxa64/libgcc_s.so.1 (0x00007f1ccb62b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1ccb419000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1ccb2ca000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1ccb2c4000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1ccb2a1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1ccb873000)
undefined symbol: _ZN5GiNaC21spinmetric_unarchiverD1Ev (/home/jros/Sync/Programming_Tricks/ginac_matlab/libginac_matlab.so)
undefined symbol: _ZN5GiNaC21diracgamma_unarchiverD1Ev (/home/jros/Sync/Programming_Tricks/ginac_matlab/libginac_matlab.so)
undefined symbol: _ZN5GiNaC17su3one_unarchiverD1Ev (/home/jros/Sync/Programming_Tricks/ginac_matlab/libginac_matlab.so)
undefined sym
....
I get undefined symbols.
same thing for my library ./ginac_matlab/libginac_matlab.so.
These symbold are from GiNaC, the library I'm calling from the library I'm interfacing.
The thing is that I can compile an executable calling my library, but I need to add -lginac to be able to compile it.
If I remove any reference to GiNaC in my library, everything goes OK in MATLAB, proving that my aproach is correct.
I have explicitly added /usr/lib to the LD_LIBRAY_PATH (just in case), restarted matlab recompiles and put everything in the MATLAB PATH.
So maybe in your case, if you add -d modeifier to ldd you will see undefined symbols as well.
It seems that the /usr/lib/libginac.so dependence in the interface library made by matlab is not properly included.
ginac_matlabInterface.so library generated by clib.
So, I suppose that the answer it to be able to tellto clib, to include a reference to libginac.
But how I do this?.
By the way, my actual invocation is:
clibgen.generateLibraryDefinition('ginac_matlab.h',OverwriteExistingDefinitionFiles=true)
I tried diferent combiantions of
Libraries=
parameter without much success.
Anyway, have you had any progress on this?.
MATLAB Support Team. PLEASE: it would be nice to have concrete reproducible example in which we define an interface to our own library, that in turn uses other (system wide or not) library. Idealy for differetn oerating systems (including Linux).
Thanks!!!!
  1 Comment
Javier Ros
Javier Ros on 20 Jun 2023
I've found a solution.
This did the trick for me:
clibgen.generateLibraryDefinition('ginac_matlab.h','Libraries',["/home/jros/Sync/Programming_Tricks/ginac_matlab/libginac_malab.so","/usr/lib/libginac.so"],OverwriteExistingDefinitionFiles=true)
And, yes it was about how to specify the set of Libraries it was dependent on.
Cheers!

Sign in to comment.

Products


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!