简体   繁体   中英

mkoctfile with multiple C and C++ source files

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM