MATLAB mex c + Fortran Ошибка
Я пытаюсь изменить проект, составленный из файлов, написанных на c и fortran. Чтобы упростить процесс, я создал следующие простые функции:
mysum.f
SUBROUTINE mysum(a,b)
REAL :: a,b,r
r = a+b
WRITE(*,*) r
END SUBROUTINE mysum
и test.c
#include <mex.h>
#include <stdio.h>
extern void mysum(double *a, double *b);
double a,b;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
a =(double) mxGetScalar(prhs[0]);
b =(double) mxGetScalar(prhs[1]);
mysum(&a,&b);
return;
}
С Intel Fortran Compiler (x64) я запускаю:
ifort / c mysum.f
и это создает mysum.obj
В Matlab (x64) я использую Microsoft SDK в качестве компилятора и пишу:
mex -O -largeArrayDims LINKFLAGS = "$ LINKFLAGS /NODEFAULTLIB:MSVCRT.lib" test.c mysum.obj
К сожалению, это дает эту ошибку:
test.obj: ошибка LNK2019: неразрешенный внешний символ mysum, на который ссылается функция mexFunction test.mexw64: фатальная ошибка LNK1120: 1 неразрешенный внешний код
В этот момент я застрял и не знаю, что делать. Я использую опцию / NODEFAULTLIB, потому что в противном случае возник конфликт с MSVCRT.lib.
Мне нужна помощь, пожалуйста.
2 ответа
Или в Fortran вы можете использовать привязку ISO C и указать имена, по которым процедуры Fortran будут видны другим языкам и компоновщику, указав регистр и не нуждаясь в подчеркиваниях. Вы также можете объявить переменные, чтобы гарантировать совместимость с Си. В вашем примере Фортран по умолчанию real
и С double
наверное не совпадают. См. https://stackru.com/questions/tagged/fortran-iso-c-binding или руководство по gfortran (оно является частью языкового стандарта и, следовательно, документация там более применима). Для этого примера:
SUBROUTINE mysum(a,b) bind ( C, name = "mysum" )
use iso_c_binding
implicit none
REAL (c_double) :: a,b,r
r = a+b
WRITE(*,*) r
END SUBROUTINE mysum
Возможно, вам нужно добавить подчеркивание к mysum в коде C:
extern void mysum_(double *a, double *b);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
//...
mysum_(&a,&b);
//...
}
Бежать nm mysum.obj
чтобы получить правильные имена для всех подпрограмм.