I have a dynamic library which I want to load into Mathematica using LibraryLink. I don't have access to the source code of the library, so I need a C wrapper to do the job. In the C wrapper, I would recieve arguments from Mathematica using the MArgument_get*
functions and call my library function to do the computation. Then, the results would be sent back to Mathematica using the MArgument_set*
functions.
Since the data type I receive from Mathematica is a Wolfram Library type such as mint
, double
, MTensor
, etc., and the data types my external library function expects to receive are standard C types like int
or float
, my question is: how do we convert between these two different data types in the wrapper so that Mathematica and my external library functions can understand each other?
Update:
Here is an very simple example, following example here.
I have defined a external function which add two vectors, in fortran:
!addvec.f90
subroutine addvec(a,b)
implicit none
integer,parameter::N=3
integer a(N),b(N)
a(:)=a(:)+b(:)
return
end subroutine addvec
The C wrapper is
//wrapper.cc
#include "WolframLibrary.h"
#include "WolframCompileLibrary.h"
DLLEXPORT mint WolframLibrary_getVersion(){
return WolframLibraryVersion;
}
DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData){
return 0;
}
extern "C" {
void addvec_(int a[], int b[]);
}
EXTERN_C DLLEXPORT int addvec(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res){
MTensor ta;
MTensor tb;
ta=MArgument_getMTensor(Args[0]);
tb=MArgument_getMTensor(Args[1]);
addvec_((int *)((*ta).data),(int *)((*tb).data));
MArgument_setMTensor(Res,ta);
return LIBRARY_NO_ERROR;
}
Mathematica code
Needs["CCompilerDriver`"]
CreateLibrary[{"wrapper.cc", "addvec.o"}, "myadd", "Debug" -> True, "TargetDirectory" -> "."]
addvec = LibraryFunctionLoad["./myadd", "addvec", {{Integer, 1}, {Integer, 1}}, {Integer, 1}]
addvec[{1, 2, 3}, {4, 5, 6}]
The Mathematica Kernel will crash soon after execute the third line.
Update 2
In Mathematica
version 9 the above code seems partially work:
addvec[{1, 2, 3}, {4, 5, 6}]
(*{5, 7, 3}*)
addvec[{1, 2, 3}, {4, 5, 6}]
(*{6, 8, 4}*)
The third number in the list is calculated wrong.