New C++ Interface with Shared Library not working (R2019a)

3 views (last 30 days)
Hello,
I have been testing the automatically generated C++ interface but ran into few problems (split into separate questions) (other question How to unload library?).
In general, I can generate and use an interface when the "header only" version is used. But as soon as I include a library (*.so) (which I think is kind of the point), the interface does not work.
I can define the interface (via clibgen.generateLibraryDefinition) and build the interface ( via e.g. build(definemyPkg)) without errors but I cannot use it (e.g. via clib.myPkg.Mat -> Undefined variable "clib" or class "clib.myPkg.Mat").
First, I tested with some basic self written test classes/files/libs, toyed around with the "auto.h" example from the blog post and after this didn't work, I tested with the example given in the docu adapted to our Linux system (see script below) (BTW, wondering why is there no Linux example?) (Define and Publish Interface to C++ Shared Library).
I admit, I am not a C++ expert or have a lot of experience with shared libraries, so if I have overseen something profoundly, please let me know.
Any help or ideas are appreciated. If you need more info or want to see the code for the other tests, let me know.
Cheers
Henning
UPDATE from Accepted Answer:
The environment variable LD_LIBRARY_PATH must be set to include the shared library file before starting MATLAB (for me, did not work when setting in MATLAB directly).
See docu (which I overlooked) System Requirements
I added a new test script.
tested on Centos7, R2019a (and quickly on RHEL8 with pre-release R2019b, which we are of course not allowed to talk about :))
Tested with compilers: gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36) and gcc (GCC) 6.3.1 20170216 (Red Hat 6.3.1-3)
This is the test script:
% adapted from
% https://de.mathworks.com/help/matlab/matlab_external/define-and-publish-matlab-interface-for-shared-library.html
% working directory is /dir/to/TestCppInterface/
%%
FolderWorking = "/dir/to/TestCppInterface/";
FolderLib = "/dir/to/TestCppInterface/linux64/gcc/";
cd(FolderWorking)
%%
copyfile(fullfile(matlabroot,'extern','examples','cpp_interface','matrixOperations.*'),'.','f')
copyfile(fullfile(matlabroot,'extern','examples','cpp_interface','cppshrhelp.hpp'),'.','f')
%%
if ~isdir('linux64')
mkdir('linux64')
if ~isdir(fullfile('linux64','gcc'))
mkdir(fullfile('linux64','gcc'))
end
end
%%
% linux
copyfile( fullfile(matlabroot,'extern','examples','cpp_interface','glnxa64','*.*'),...
fullfile('linux64','gcc'),'f')
%%
% path = getenv('path'); % windows example with lower case
path = getenv('PATH');
%%
setenv('PATH', [ char(FolderWorking) ':' char(FolderLib) ':' path]);
%%
% Full path to files in the library
% productPath = 'H:\Documents\MATLAB\publisher\matrixexample';
productPath = char(FolderWorking);
% Header file name
hppFile = 'matrixOperations.hpp';
% Full path to folder containing all header files
hppPath = productPath;
% Full path to folder containing include files
iPath = hppPath;
% Full path to folder containing library files. This example uses the MinGW-w64 compiler.
% libPath = fullfile(productPath,'win64','mingw64');
libPath = fullfile(productPath,'linux64','gcc');
% Library file name
% libFile = 'matrixOperations.lib';
libFile = 'libmwmatrixOperations.so';
%%
myPkg = 'myPkg';
%%
v = true;
clibgen.generateLibraryDefinition(fullfile(hppPath,hppFile),...
'IncludePath', iPath,...
'Libraries', fullfile(libPath,libFile),...
'PackageName', myPkg,...
'Verbose',v)
%%
% complete the missing definitions as required (or just build with missing
% methods)
%%
build(definemyPkg)
%%
addpath('./myPkg')
%%
matObj = clib.myPkg.Mat; % not working
% Undefined variable "clib" or class "clib.myPkg.Mat"
New, adapted script:
%%
%
%
%
% adapted from
% https://de.mathworks.com/help/matlab/matlab_external/define-and-publish-matlab-interface-for-shared-library.html
%
% see also answer on MathWorks forum
% https://de.mathworks.com/matlabcentral/answers/472129-new-c-interface-with-shared-library-not-working-r2019a
% working directory is /dir/to/TestCppInterface/
%%
% IMPORTANT NOTE
% On Linux, make sure the environment variable `LD_LIBRARY_PATH` includes
% the path to the lib that is to be used BEFORE starting MATLAB.
% For example, for this example script
% ~~~
% setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH:/dir/to/TestCppInterface/linux64/gcc
% echo $LD_LIBRARY_PATH
% matlab
% ~~~
%%
FolderWorking = "/dir/to/TestCppInterface/";
cd(FolderWorking)
%%
copyfile(fullfile(matlabroot,'extern','examples','cpp_interface','matrixOperations.*'),'.','f')
copyfile(fullfile(matlabroot,'extern','examples','cpp_interface','cppshrhelp.hpp'),'.','f')
%%
if ~isdir('linux64')
mkdir('linux64')
if ~isdir(fullfile('linux64','gcc'))
mkdir(fullfile('linux64','gcc'))
end
end
%%
% linux
copyfile( fullfile(matlabroot,'extern','examples','cpp_interface','glnxa64','*.*'),...
fullfile('linux64','gcc'),'f')
%%
% just to check that the path to the lib is included
TmpLDPath = getenv("LD_LIBRARY_PATH")
%%
% Full path to files in the library
% productPath = 'H:\Documents\MATLAB\publisher\matrixexample';
productPath = char(FolderWorking);
% Header file name
hppFile = 'matrixOperations.hpp';
% Full path to folder containing all header files
hppPath = productPath;
% Full path to folder containing include files
iPath = hppPath;
% Full path to folder containing library files. This example uses the MinGW-w64 compiler.
% libPath = fullfile(productPath,'win64','mingw64');
libPath = fullfile(productPath,'linux64','gcc');
% Library file name
% libFile = 'matrixOperations.lib';
libFile = 'libmwmatrixOperations.so';
%%
myPkg = 'myPkg';
%%
v = true;
clibgen.generateLibraryDefinition(fullfile(hppPath,hppFile),...
'IncludePath', iPath,...
'Libraries', fullfile(libPath,libFile),...
'PackageName', myPkg,...
'Verbose',v)
%%
% complete the missing definitions as required (or just build with missing
% methods)
%%
build(definemyPkg)
%%
addpath('./myPkg')
%%
matObj = clib.myPkg.Mat;

Accepted Answer

Vivek
Vivek on 18 Jul 2019
Hi Henning,
Thanks for trying this out! I think you need to set the LD_LIBRARY_PATH (on Windows, we set PATH) so that the system can find the '.so' you want to call.
setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH:/<your_so_path>
For example
setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/local/lib
Please note that if you have any dependencies that the main library needs, then they also need to be added to the LD_LIBRRAY_PATH. Hope that resolves the issue.
Vivek
  6 Comments
BRSC User
BRSC User on 17 Apr 2020
> Thanks for your feedback on the documentation, we are working on an example for Linux. (19 Jul 2019)
I need to use a set of C/C++ interfaces (defined in header and implemented in a shared library which depends on other linux pkgs - e.g. Eigen::Vector and Matrix). I would like to try this framework (instead of mexFunction). Please let me know if the working example for Linux is available.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!