I am not able to have mkoctfile
to successfully create an oct
file that is a wrapper of some C++
function of mine (eg void my_fun(double*,double)
). In particular my problem rises from the fact that, the wrapper code my_fun_wrap.cpp
requires the inclusion of the <octave/oct.h>
library which only provides C++
headers (see here ), but the original code of my_fun
also uses source code that is in C
. Eg
// my_fun_wrapper.cpp
#include <octave/oct.h>
#include "custom_functions_libc.h"
DEFUN_DLD(my_fun_wrapper,args, , "EI MF network model A with delays (Brunel, JCN 2000)"){
// Input arguments
NDArray xvar = args(0).array_value();
double x = xvar(0);
// Output arguments
double dy[4];
dim_vector dv (4,1);
NDArray dxvars(dv);
// Invoke my C function which also includes code in the lib file custom_functions_libc.c
my_fun(dy,x);
// Then assign output value to NDArray
for(int i=0;i<4;i++) dxvars(i) = dy[i];
// Cast output as octave_value as required by the octave guidelines
return octave_value (dxvars);
}
Then suppose that my custom_functions_libc.h
and custom_functions_libc.c
files are somewhere in a folder <path_to_folder>/my_libs
. Ideally, from Octave command line I would compile the above by:
mkoctfile -g -v -O -I<path_to_folder>/my_libs <path_to_folder>/my_libs/custom_functions_libc.c my_fun_wrapper.cpp -output my_fun_wrapper -lm -lgsl -lgslcblas
This actually generates my_fun_wrapper.oct
as required. Then I can call this latter from within some octave
code, eg
...
...
xx = [0., 2.5, 1.];
yy = [1e-5, 0.1, 2.];
dxv = test_my_function(xx,yy);
function dy = test_my_function(xx,yy)
xx += yy**2;
dy = my_fun_wrapper(xx);
endfunction
It turns out that the above code will exit with an error in test_my_function
saying that within the my_fun_wrapper
the symbol Zmy_fundd
is not recognized. Upon receiving such kind of error I suspected that something went wrong on the linking process. But strangely enough the compiler did not produce any error as I said. Yet, a closer inspection of the verbose output of the compiler revealed that mkoctfile
is changing compiler automatically between different files depending on their extension. So my_fun_wrapper.cpp
is compiled by g++ -std=gnu++11
but custom_function_libc.c
is compiled by gcc -std=gnu11
and somehow the custom_function_libc.o
file ensuing by this compilation process, when linked with my_fun_wrapper.o
does not matches unresolved symbols.
The example above is very simplistic. In practice, in my case custom_function_libc
includes many more custom C
libraries. A workaround so far was to clone the .c
source file for those libraries into .cpp
files. But I do not like this solution very much.
How can I eventually mix C++
and C
code safely and compile it successfully by mkoctfile
? octave
manual suggests to prepend an extern C
specification (see here ) which I am afraid I am not very familiar with. Is this the best way? Could you suggest me alternatively, a potential alternative solution?
So apparently the easiest solution, according to my above post is to correct the wrapper by the following preprocessor directives:
// my_fun_wrapper.cpp
#include <octave/oct.h>
// ADDED code to include the C source code
#ifdef __cplusplus
extern "C"
{
#endif
// END ADDITION
#include "custom_functions_libc.h"
// ADDED code to include the C source code
#ifdef __cplusplus
} /* end extern "C" */
#endif
// END ADDITION
...
...
This will compile and link fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.