Question

I'm trying to mex a project made up of files written in c and fortran. In order to make it easy I created this simple funcions:

mysum.f

  SUBROUTINE mysum(a,b)
  REAL :: a,b,r

  r = a+b
  WRITE(*,*) r
  END SUBROUTINE mysum

and 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;
}

With Intel Fortran Compiler (x64) I run:

ifort /c mysum.f

and it creates mysum.obj

In Matlab (x64) I'm using Microsoft SDK as compiler and I write:

mex -O -largeArrayDims LINKFLAGS="$LINKFLAGS /NODEFAULTLIB:MSVCRT.lib" test.c mysum.obj

Unfortunatelly it gives this error:

test.obj : error LNK2019: unresolved external symbol mysum referenced in function mexFunction test.mexw64 : fatal error LNK1120: 1 unresolved externals

At this point I'm stuck and I don't know what to do. I'm using the option /NODEFAULTLIB because there was a conflict otherwise with MSVCRT.lib.

I need some help please.

Was it helpful?

Solution

Or in the Fortran you can use the ISO C Binding and specify the names by which Fortran procedures will be seen by other languages and the linker, specifying case and not needing underscores. You can also declare variables so that compatibility with C is guaranteed. In your example, Fortran default real and C double probably don't match. See https://stackoverflow.com/questions/tagged/fortran-iso-c-binding or the gfortran manual (its part of the language standard and so the documentation there is more generally applicable). For this example:

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

OTHER TIPS

You probably need to append an underscore to mysum in the C code:

extern void mysum_(double *a, double *b);

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
//...
  mysum_(&a,&b);
//...
}

Run nm mysum.obj to get the correct names for all subroutines.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top