11
$\begingroup$

I'm trying to find out the way to use c-functions in Mathematica (I'm using 14 version) on OS X 10.10.

For example I've got this lines of code:

#include <stdio.h>
double helloWorld(double a) {
    return 2 * a;
}

Then I've tried to make a shared library like this:

gcc -dynamiclib -o mylib.dylib hello.c

After that I'm trying to load this function in mathematica:

LibraryFunctionLoad["~/term/mylib.dylib", "helloWorld", {Real}, Real];

But mathematica tells me that it cannot load my function

LibraryFunction::libload: The function helloWorld was not loaded from the file ~/term/mylib.dylib. >>

Is anyone has clue how to make this things work?

$\endgroup$
3
  • $\begingroup$ Is your function helloWorld visible in your library? I don't see anything to export (make public) that symbol. I've done this before, on windows where you have to explicitly declare which functions in a dll are to be visible. If you don't they aren't. It may be different in OS X of course. $\endgroup$
    – Ymareth
    Commented Nov 13, 2014 at 9:16
  • $\begingroup$ I guess they are visible $ nm -a libksr.dylib 0000000000000f70 T _helloWorld U dyld_stub_binder $\endgroup$
    – Alex
    Commented Nov 13, 2014 at 9:24
  • 2
    $\begingroup$ I believe this is a duplicate of mathematica.stackexchange.com/q/8438/12 LibraryFunctionLoad is meant to be used only with functions specifically written for LibraryLink. If you are going to use LibraryLink, you will need to create a LibraryLink-compatible wrapper for whatever you need to call. There are other methods than LibraryLink for calling C functions, all described in the thread I linked. $\endgroup$
    – Szabolcs
    Commented Nov 21, 2014 at 20:03

1 Answer 1

12
+50
$\begingroup$

You can look here for more examples and details:

In short, do the following (call the file DoubleIt.c):

#include "WolframLibrary.h"

 DLLEXPORT int DoubleIt(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
         mint x;
         mint result;
         x = MArgument_getInteger(Args[0]);
         result = 2*x;
         MArgument_setInteger(Res,result);
        return LIBRARY_NO_ERROR;
}

Then, in Mathematica, do the following (you will need a compiler on your machine):

Needs["CCompilerDriver`"];

lib = CreateLibrary[{"DoubleIt.c"},"DoubleIt"];
DoubleIt = LibraryFunctionLoad[lib,"DoubleIt",{Integer},Integer];

Then you can use it as a function:

DoubleIt[4]

That should return the integer 8. You can also do this with real numbers, but you will need to change the various Integer functions to use Real. So:

#include "WolframLibrary.h"

DLLEXPORT int DoubleIt2(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
     mreal x;
     mreal result;
     x = MArgument_getReal(Args[0]);
     result = 2*x;
     MArgument_setReal(Res,result);
    return LIBRARY_NO_ERROR;

}

And:

lib = CreateLibrary[{"c:\\users\\arnoudb.wri\\DoubleIt2.c"}, "DoubleIt2"];
DoubleIt2 = LibraryFunctionLoad[lib, "DoubleIt2", {Real}, Real];

And then:

DoubleIt2[4.2]

(Which gives 8.4)

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.