Почему Matlab не связывает мой код C MEX? - PullRequest
1 голос
/ 24 октября 2011

У меня есть следующая проблема при компиляции моих mex C-функций с использованием компилятора MS VC ++: у меня есть функция disc_rhs__ в отдельном файле disc_rhs.c, созданная f2c (что должно быть неважно, но ...).В моей основной функции я пишу куда-то

...
disc_rhs__(...);
...

Я пытаюсь скомпилировать, используя

mex sfun_kalman.cpp -L. -llapack -lcblas_WIN -lblas_WIN -lf2c disc_rhs.c kalmanfilter_f2c.cpp

Это приводит к ошибке.Компоновщик не может найти внешний символ ""int __cdecl disc_rhs__(double *,double *,double *,double *,double *)" (?disc_rhs__@@YAHPAN0000@Z)", используемый в kalmanfilter.cpp.

Чтобы получить все, что компилируется, я скопировал disc_rhs.cpp в disc_rhs.h и удалил объявление функции, просто добавив заглушку.Это я включил в kalmanfilter.h.

Так почему же компилятор Matlab Mex не распознает символ corrct и не связывает его с компиляцией disc_rhs.c?

Спасибо, Кристиан

1 Ответ

1 голос
/ 24 октября 2011

Не помещайте все содержимое disc_rhs.cpp в заголовочный файл, а затем включите его в другой файл. Это будет работать только до тех пор, пока этот файл включен в один исходный файл, как только вы включите его в другой исходный файл, вы получите несколько ошибок определения.

Правильный способ решить эту проблему - создать файл disc_rhs.h, содержащий прототипы всех функций из disc_rhs.cpp, которые должны использоваться другими модулями. Затем вы включите заголовочный файл в kalmanfilter.cpp (и любые другие файлы, которые должны использовать эти функции).

EDIT:
Ошибка возникает из-за того, что файл disc_rhs имеет расширение .c , что заставляет MSVC скомпилировать его как файл C. Однако, поскольку он используется в kalmanfilter.cpp, компоновщик ожидает найти функцию C ++ с искаженным именем, которой не существует. Чтобы решить эту проблему, вы должны сообщить компилятору, что disc_rhs__() является функцией C.

In disc_rhs.h

#ifdef __cplusplus
extern "C" 
#endif
int disc_rhs__(double *,double *,double *,double *,double *);

Директива extern "C" должна появляться перед каждым экспортируемым элементом с помощью disc_rhs.c, поэтому, если у вас есть несколько вещей, которые нужно экспортировать, следующий синтаксис более удобен.

#ifdef __cplusplus
extern "C" {
#endif
int disc_rhs__(double *,double *,double *,double *,double *);

// other stuff being externed

#ifdef __cplusplus
}
#endif
...