1

Swigを使用してCとTCLを組み合わせるチュートリアルに従っています。チュートリアルは適切に機能しているように見えましたが、最後に解決できないエラーに遭遇しました。状況は次のとおりです。

私がフォローしていたチュートリアルは http://www.swig.org/tutorial.htmlです。

test.c という名前のファイルがあります。

char *HelloWorld()
{
    return "hello world";
}

および別の名前の test.i:

%module test
%{
/* Put header files here or function declarations like below */
extern char *HelloWorld();
%}

extern char *HelloWorld();

次に、次のコマンド ライン引数を使用して、正しいファイルを準備しました。

gcc -c test.c -o test.o
swig -tcl test.i 
gcc -c test_wrap.c -o test_wrap.o
gcc -dynamiclib -framework Tcl  test.o test_wrap.o -o test.so

そして最後に、次を使用してロードしようとしました:

tclsh
% load test.so test

これは、次のエラーを受け取ったポイントです。

dlsym(0x100600090, Test_Unload): symbol not founddlsym(0x100600090, Test_SafeUnload): symbol not found

私の知る限り、私はチュートリアルから外れていません。このエラーが発生した理由と、さらに重要なことに、それを取り除く方法を誰か教えてもらえますか?

前もって感謝します!

4

2 に答える 2

1

これらのエラー メッセージは のload動作を妨げていますか? すべきではありません。彼らは、拡張機能のアンロードをサポートするための低レベル API が存在しないと報告していますが、それは問題ありません (多くの拡張機能はアンロードできません。それをサポートするコードを書くのは難しいです)。

使用している Tcl のバージョンについては正確には言及していませんが、最初にこれらのシンボルを検索するには、少なくとも 8.5 である必要があります。したがって、正確な根本的な問題が何であるかを推測するのは少し困難です。(このメッセージは単に報告されるべきではありません。)これに関するバグ レポートを提出することをお勧めします。レポートには正確なバージョンがすべて含まれていることを確認してください。

于 2011-09-22T08:24:57.477 に答える
0

SWIG を使用してから長い時間が経過したため、この修正プログラムを適用するために、SWIG が生成するコードを十分に制御できるかどうかはわかりません。その詳細を詳しく調べると、次の方法で問題を再現 (および修正) できます。

「ext.c」では:

#include <tcl.h>

int DLLEXPORT Ext_Init(Tcl_Interp *interp) {


    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
        return TCL_ERROR;
    }
    if (Tcl_PkgProvide(interp, "Ext", "0.0") == TCL_ERROR) {
        return TCL_ERROR;
    }

    return TCL_OK;
}

ビルド、tclsh の実行、拡張機能のロード:

$ gcc -dynamiclib -framework Tcl ext.c -o ext.so
$ tclsh8.5
% load ./ext.so
dlsym(0x400000, Ext_SafeInit): symbol not found
dlsym(0x400000, Ext_Unload): symbol not found
dlsym(0x400000, Ext_SafeUnload): symbol not found

ライブラリをロードするコードの内部の何かが、そのエラーメッセージをインタープリターの結果に入れています。メッセージが表示されないようにするには、結果を設定またはリセットして、_Init() 関数が次のいずれかで終了するようにします。

//    Set the result to a message of your choosing
    Tcl_SetObjResult(interp, Tcl_NewStringObj("ok", -1));

//    Or clear out the result altogether
    Tcl_ResetResult(interp);
    return TCL_OK;
}

swigのinit ブロック機能は、同じことを実現するために適切な場所にコードを挿入する場合があります

%init %{
Tcl_ResetResult(interp);
%}
于 2012-04-03T14:50:07.230 に答える