Wolfram LibraryLink を使うと,ダイナミックライブラリを Mathematica カーネルに直接ロードして,ライブラリの関数を即座に Mathematica 内部から呼び出せるようにすることができる.整数,実数,パックアレー,文字列等のCのようなデータ型だけでなく,任意の Mathematica 式も交換することができる.また,エラーを送ったり,Mathematica にコールバックしたりするような便利な関数もある.

ドキュメントにはWolfram Librariesの例がたくさん含まれている.これらには Mathematica からライブラリを呼び出す際のさまざまな側面を例示する多くの短い関数が含まれている.

例を使う

ドキュメントにはサンプルライブラリのソースが含まれている.ライブラリの構築にはCコンパイラへのアクセスが必要となる.CCompilerDriverパッケージが役立つかもしれない.

使用中のプラットフォームでデモサンプルが見付かったことを示している.

In[1]:=
Click for copyable input
Out[1]=

demo例題ライブラリから関数をロードする.

In[2]:=
Click for copyable input
Out[2]=

関数を呼び出す.

In[3]:=
Click for copyable input
Out[3]=

ソース

例題のソースはドキュメントパクレットにある.これは次の入力を評価すると見付かる.

In[4]:=
Click for copyable input
Out[4]=
demo.c基本例題のサンプル
demo_shared.c共有渡しの基本例題のサンプル
demo_error.cエラーキャッチのサンプル
demo_string.c文字列引数と結果を使ったサンプル
demo_mathlink.c引数と結果指定にLinkObjectを使ったサンプル

ライブラリ例題ソースファイル

demo

demoの例題には多くの関数が含まれている.以下はそれを使う例である

In[5]:=
Click for copyable input
Out[6]=

demo_shared

demo_sharedの例題にはパックアレーをライブラリ関数と共有する例題が含まれている.以下で多数の関数をロードする.

In[7]:=
Click for copyable input

パックアレーを作成し,ライブラリにロードする.共有メモリ渡しが使われるため,配列は他の関数呼出しで使える.

In[10]:=
Click for copyable input
Out[11]=

10番目の要素である10を取得する.

In[12]:=
Click for copyable input
Out[12]=

配列をアンロードする.その後はこの配列は使えなくなる.

In[13]:=
Click for copyable input
Out[13]=

いくつかの関数のソースである.

DLLEXPORT int loadArray(WolframLibraryData libData,
            mint Argc, MArgument *Args, MArgument Res) {

    tensor = MArgument_getMTensor(Args[0]);
    MArgument_setInteger(Res, 0);
    return LIBRARY_NO_ERROR;
}

DLLEXPORT int getElementVector(WolframLibraryData libData,
            mint Argc, MArgument *Args, MArgument Res) {
    mint pos;
    double value;
    
    pos = MArgument_getInteger(Args[0]);
    value = libData->MTensorVector_getReal( tensor, pos);
    
    MArgument_setReal(Res, value);
    return LIBRARY_NO_ERROR;
}

DLLEXPORT int unloadArray(WolframLibraryData libData,
            mint Argc, MArgument *Args, MArgument Res) {

    libData->MTensor_disown( tensor);
    MArgument_setInteger(Res, 0);
    return LIBRARY_NO_ERROR;
}

demo_error

demo_errorの例題はエラーを引き起こす関数呼出しの例を含む.ライブラリから関数をロードする.

In[14]:=
Click for copyable input

errordemo1関数のソースである.MTensor引数を取り,実数データの取得を試みる.

DLLEXPORT int errordemo1(WolframLibraryData libData,
            mint Argc, MArgument *Args, MArgument Res) {
    MTensor T0, T1;
    mint I0, I1, res;
    mint pos[2];
    double *data;

    T0 = MArgument_getMTensor(Args[0]);
    I0 = MArgument_getInteger(Args[1]);
    
    data = libData->MTensor_getRealData(T0);
    MArgument_setReal(Res, data[I0]);
    return LIBRARY_NO_ERROR;
}

例題は整数MTensorを取る.関数はMTensor_getRealDataを呼び出すがこれがエラーとなり,LibraryFunctionError式を返す.

In[15]:=
Click for copyable input
Out[15]=

demo_string

demo_stringの例題は要求されたメモリ管理で文字列の引数と結果を使う方法を示す.ASCII文字列に対して簡単なシフト暗号化を行う関数をロードする.

In[17]:=
Click for copyable input

以下がエンコーディング関数のソースである.引数はエンコードする文字列で,整数シフトが適用される.

DLLEXPORT int encodeString(WolframLibraryData libData,
        mint Argc, MArgument *Args, MArgument Res)
{
    mint i = 0, shift;
    
    if (string)
        libData->String_disown(string);

    string = MArgument_getUTF8String(Args[0]);
    shift = MArgument_getInteger(Args[1]);

    /* Find shift mod 127 so we only
     deal with positive numbers below */
    shift = shift % 127;
    if (shift < 0)
        shift += 127;

    shift -= 1;
        
    while (string[i]) {
        mint c = (mint) string[i];
        /* Error for non ASCII string */
        if (c & 128) return DLL_FUNCTION_ERROR;
        c = ((c + shift) % 127) + 1;
        string[i++] = (char) c;
    }
    MArgument_setUTF8String(Res, string);
    return LIBRARY_NO_ERROR;
}

これが例題である.

In[18]:=
Click for copyable input
Out[18]=

文字列参照は関数外のスコープの変数に保管される.この参照は関数が再び呼ばれ(そして新しい文字列が参照され)るか,(関数WolframLibrary_uninitializeの中で)ライブラリがアンロードされるかすると解放される.文字列引数のメモリはライブラリ関数がすべて所有するので,メモリ内でインプレースエンコーディングが行われ,別の文字列への割当てを必要としない.

demo_mathlink

demo_mathlinkの例題は,引数と結果の指定としてLinkObjectを使う例を示す.ライブラリから関数をロードする.

In[19]:=
Click for copyable input

以下はreverseString関数のソースである.MLINK引数を取り,MathLink APIを使ってリスト中の引数を読み取る.結果は生成されるとリンク上に書き出される.

DLLEXPORT int reverseString( WolframLibraryData libData, MLINK mlp)
{
    int res = LIBRARY_FUNCTION_ERROR;
    long len;
    const char *inStr = NULL;
    char* outStr = NULL;
    
    if ( !MLCheckFunction( mlp, "List", &len))
        goto retPt;
    if ( len != 1)
        goto retPt;

    if(! MLGetString(mlp, &inStr))
        goto retPt;

    if ( ! MLNewPacket(mlp) )
        goto retPt;

    outStr = reverseStringImpl(inStr);
    
    if (!MLPutString( mlp,outStr))
        goto retPt;
    res = 0;
retPt:
    if ( inStr != NULL)
        MLReleaseString(mlp, inStr);
    if ( outStr != NULL)
        free( (void*) outStr);
    return res;
}

文字列を渡す,結果がリンクから読み取られ,表示される.

In[20]:=
Click for copyable input
Out[20]=
New to Mathematica? Find your learning path »
Have a question? Ask support »