Reputation: 1237
I have the following problem in compiling my mex C functions using MS VC++ Compiler: I have a function disc_rhs__
in a separate file disc_rhs.c
which was createtd by f2c (which should be unimportant, but...). In my main function I write somewhere
...
disc_rhs__(...);
...
I try to compile using
mex sfun_kalman.cpp -L. -llapack -lcblas_WIN -lblas_WIN -lf2c disc_rhs.c kalmanfilter_f2c.cpp
This leads to an error. The linker cannot find the external symbol ""int __cdecl disc_rhs__(double *,double *,double *,double *,double *)" (?disc_rhs__@@YAHPAN0000@Z)"
used in the kalmanfilter.cpp
.
To get everything compiling I copied the disc_rhs.cpp
to disc_rhs.h
and removed the function declaration just letting a stub. This I included in kalmanfilter.h
.
So why does matlab mex compiler not recognize the corrct symbol and link with the compilation of disc_rhs.c
?
Thanks Christian
Upvotes: 1
Views: 550
Reputation: 109279
Do not put the entire contents of disc_rhs.cpp
into a header file and then include it in another file. This will only work as long that file is being included by a single source file, as soon as you include it in another source file you'll get multiple definition errors.
The right way to fix this problem is to create a disc_rhs.h
file that contains the prototypes of all functions from disc_rhs.cpp
that need to be used by other modules. Then you'd include the header file in kalmanfilter.cpp
(and any other files that need to use those functions).
EDIT:
The error is happening because the disc_rhs
file has a .c extension which causes MSVC to compile it as a C file. However, since it is being used in kalmanfilter.cpp
the linker is expecting to find a C++ function that has been name mangled, which doesn't exist. To fix the problem, you need to tell the compiler that disc_rhs__()
is a C function.
In disc_rhs.h
#ifdef __cplusplus
extern "C"
#endif
int disc_rhs__(double *,double *,double *,double *,double *);
The extern "C"
directive needs to appear in front of each item being exported by disc_rhs.c
, so if you have several things to extern, the following syntax is more convenient.
#ifdef __cplusplus
extern "C" {
#endif
int disc_rhs__(double *,double *,double *,double *,double *);
// other stuff being externed
#ifdef __cplusplus
}
#endif
Upvotes: 1