У меня нет возможности mkoctfile
для успешного создания файла oct
, который является оболочкой для какой-то моей C++
функции (например, void my_fun(double*,double)
). В частности, моя проблема возникает из-за того, что код оболочки my_fun_wrap.cpp
требует включения библиотеки <octave/oct.h>
, которая предоставляет только заголовки C++
(см. здесь ), но оригинальный код my_fun
также использует исходный код, который находится в C
. Э.Г.
// 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);
}
Тогда предположим, что мои custom_functions_libc.h
и custom_functions_libc.c
файлы находятся где-то в папке <path_to_folder>/my_libs
. В идеале, из командной строки Octave я бы скомпилировал вышеперечисленное:
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
Это фактически генерирует my_fun_wrapper.oct
, как требуется. Затем я могу назвать этот последний из некоторого кода octave
, например
...
...
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
Оказывается, что вышеприведенный код завершится с ошибкой в test_my_function
, говорящей о том, что внутри my_fun_wrapper
символ Zmy_fundd
не распознается. Получив такую ошибку, я подозревал, что в процессе компоновки что-то пошло не так. Но как ни странно, как я уже сказал, компилятор не выдал никакой ошибки. Тем не менее, более тщательная проверка подробного вывода компилятора показала, что mkoctfile
автоматически меняет компилятор между различными файлами в зависимости от их расширения. Таким образом, my_fun_wrapper.cpp
компилируется с помощью g++ -std=gnu++11
, а custom_function_libc.c
компилируется с помощью gcc -std=gnu11
, и каким-то образом файл custom_function_libc.o
, полученный в результате этого процесса компиляции, когда связанный с my_fun_wrapper.o
не соответствует неразрешенным символам.
Пример выше очень упрощен. На практике в моем случае custom_function_libc
включает в себя гораздо больше пользовательских библиотек C
. Обходной путь до сих пор заключался в клонировании исходного файла .c
для этих библиотек в файлы .cpp
. Но мне не очень нравится это решение.
Как в конечном итоге можно безопасно смешать C++
и C
код и успешно скомпилировать его с помощью mkoctfile
? Руководство octave
предлагает добавить extern C
спецификацию (см. здесь ), с которой, я боюсь, я не очень знаком. Это лучший способ? Не могли бы вы предложить мне альтернативное, потенциальное альтернативное решение?