How can I call functions inside a shared object file (*.so) using C code inside an s-function in a linux environment?

조회 수: 79 (최근 30일)
Hello, I am working to establish a workflow/toolchain for a project that dives into the weeds of s-functions and Simulink, and I've built out a ficticious scenario as an example to get some advice since I cannot disclose the actual details of the project. Because of the complexity, let me explain what is going on in detail in two parts:
  1. The piece of the project that does work (I'll give an explaination of this since *.so files are likely not common knowledge)
  2. The piece of the project I am struggling with (which involves Simulink and S-Functions)
Part 1: The Scenario
I have some C code that I'd like to use inside an s-function in Simulink, which consists of two files; "myMath.c" & "myMath.h". The "myPoly()" functions compute some different polynominal functions in this example. Unfortunately, instead of getting the C source code directly, I am given a shared object file *.so (the Linux equivalent of a Windows *.dll dynamically-linked-library) of compiled C code to use. This library is named "libmyMath.so".
I am working inside of a generic Linux OS (Red-Hat to be exact). I know the names of the functions inside of the *.so, as well as the data-types of the inputs & outputs, but not of the internals of the functions themselves. I cannot simply "#include" the header file associated with the library because in this scenario, I only have access to the "libmyMath.so" file. My directory is organized as:
  • main.c
  • myLib (directory)
  • --> libmyMath.so
Outside of the MATLAB environment, I know how to make use of this shared object library "libmyMath.so". I'll post a snippet of the C code that is complied and executes from the "libmyMath.so" file during run-time. This is done via the header file "<dlfcn.h>, which provides functions to call the shared object symbols stored inside.
Now, in a bash terminal outside of the MATLAB environment, I can compile this project using the command:
user@machine pwd: $ gcc -ldl main.c -o exe
And this does in fact build the executable "exe" which can call the functions within "myMath.c" during run time, while only using the "libmyMath.so" file and nothing else.
Everything in Part 1 is functional, and I gave an in-depth description here as I assume most people are not familiar with shared object files and the link.
Now I would like to recreate this process inside of a S-Function within Simulink, this is where Part 2 comes in.
Part 2: Calling a Shared Object (*.so) inside of an S-Function
So now, let's assume that I would like to call the "myPoly1()" function inside of an S-Function, and the only way I can call that function is from the "libmyMath.so" file. I have been using the S-Function Builder tool in the Simulink library broswer to build my own Level-2 S-Function. Here is what I have:
First, here is a very simple Simulink model. The input is a ramp that goes from values 0 to 10. This input is feed into the S-Function that I am trying to configure, and this is where the problems occur. (Ignore the read around the ramp function, I define the slope in a separate *.m file, and those parameters are just currently not in my Workspace. It's a simple fix)
Here is how I have the S-Function Builder configured. It demonstrates how I have my code configured. This is the piece where I need assitance!
As you can see, the S-Function Builder cannot find the <dlfcn.h> library. I verified the path to the "dlfcn.h" using the "-H" flag during compilation in Part 1. I've tried to configure "library" and "include" paths and their entries but I can't seem to get past this error.
So here is the question: Can someone please show me how to configure this Builder tool so I can call functions from my *.so file?
Here is some additional information, just in case:
  • Using MATLAB 2021b currently (although eventually this will need to run on 2019b)
  • Red-Hat Linux, Version 7
  • 'mex' is calling: gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Additionally, here is the code for both parts 1 & 2 are attached in case anyone needs to experiment with the code a little bit.
  • Part 1: LSO-test2.zip
  • Part 2: SFB-test3.zip
  댓글 수: 6
David
David 2022년 6월 14일
Hey Walter, could you elaborlate on the additional C++ possibilities? I know in my example I am strickly using C, however once I prove out this toolchain I'll be incorporating some C++ as well.
Additionally, I don't believe the 'coder.ceval' tool is the right path forward. The reason why is that in the S-Function builder tool, all the code I provide in that window is in C. I can't call MATLAB functions from inside that block. If other S-Function templates exist, then perhaps it could be possible.
I was able to use the *.so functions inside of Simulink, but not in the way I expect. I don't want this to be my final solution just yet, however here is a possibility.
Rather than using an S-Function, I used a MATLAB function block and used the same techniques from my previous comment.
To load the library, I call the 'loadlibrary()' function in the "Start Fcn" block in Model Properties. (Go to the Modeling Tab, select the 'model parameters' options in the drop-down menu, and move to the Callbacks tab and add your code to the appropiate section". )
Then inside of the MATLAB function, I have the following code. It makes uses of the 'coder.extrinsic' functionality to use native MATLAB functions that are not supported in Simulink inside of these blocks. See below:
Then at the end of the simulation, I unload the library accordingly.
This process does work successfully, see the output below:
But this still does not answer my origional question. When I go back to my origional project, converting every block in our massive simulation from S-Functions to MATLAB function blocks will be an expensive brute-force effort. I would still rather use S-Functions, any ideas on how to accomplish this?
Suman
Suman 2024년 4월 29일
Hi David,
It seems that the INC_PATH for the dlfcn.h is incorrect. You can try just specifying the path to the directory containing the header file instead of full path to the file.
>> INC_PATH=/usr/include
I hope that helps!

댓글을 달려면 로그인하십시오.

답변 (1개)

Kautuk Raj
Kautuk Raj 2024년 12월 5일 4:17
To configure the S-Function Builder to use your shared object (*.so) file in Simulink, you can follow a similar approach to using DLL files as described in the following MATLAB Answers post: https://www.mathworks.com/matlabcentral/answers/91975-how-can-i-use-a-dll-file-in-simulink
I hope this guidance helps you successfully integrate your shared object file into Simulink using the S-Function Builder.

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by