2016-07-08 7 views
1

TCLスクリプトとC++拡張の作業セットがありますが、どのように動作し、どのようにコンパイルされたのかはわかりません。私はgccとlinux Archを使用しています。マクロとメイン関数なしでTCLのC++拡張機能をコンパイルする方法

次のように動作します.test.tclスクリプトを実行すると、C++拡張機能に定義されたクラスのオブジェクトにいくつかの値が渡されます。これらの値を使用すると、マクロを使った拡張が結果を与え、グラフィックスをいくつか出力します。

私が持っているtest.tclはスクリップで:

#!object 

use_namespace myClass 

proc simulate {} { 
    uplevel #0 { 
     set running 1 
     for {} {$running} { } { 
     moveBugs 
     draw .world.canvas 
     .statusbar configure -text "t:[tstep]" 
    } 
    } 
} 

set toroidal 1 
set nx 100 
set ny 100 
set mv_dist 4 
setup $nx $ny $mv_dist $toroidal 

addBugs 100 

# size of a grid cell in pixels 
set scale 5 
myClass.scale 5 

object.ccは、次のようになります。

#include //some includes here 

MyClass myClass; 
make_model(myClass); // --> this is a macro! 

次のようにマクロ "make_model(MyClassの)は、" 拡大:

 namespace myClass_ns { DEFINE_MYLIB_LIBRARY; int TCL_obj_myClass 
(mylib::TCL_obj_init(myClass),TCL_obj(mylib::null_TCL_obj, 
(std::string)"myClass",myClass),1); }; 

クラスの定義は次のとおりです。

class MyClass: 
{ 
public: 
    int tstep; //timestep - updated each time moveBugs is called 
    int scale; //no. pixels used to represent bugs 
    void setup(TCL_args args) { 
    int nx=args, ny=args, moveDistance=args; 
    bool toroidal=args; 
    Space::setup(nx,ny,moveDistance,toroidal); 
    } 

すべてが、あるセルから別のセルに移動するいくつかのドット(バグ)を持つセルグリッドを作成します。

私の質問は以下のとおりです。

  • はどのようにクラスメソッドと変数は、スクリプト値を得るのですか?
  • C++コードをメイン関数なしでコンパイルするにはどうすればよいですか?
  • エクステンション内でマクロが何をしているのか、それがどのように機能しているのですか?

のTclでコマンドが実行されるたびに感謝

答えて

2

は、そのコマンドを実装する関数を呼び出します。その関数はCやC++のような言語で書かれ、引数に渡されます(文字列またはTcl_Obj*の値)。完全な拡張には、ライブラリの初期化を行う関数も含まれます。あなたのライブラリがfoo.dllの場合は、外部(Cリンケージを持ち、名前がFoo_Init)は、実装関数をコマンドとして登録するような基本的な設定作業を行います。が初期化されています。

実装機能は、彼らが望むほとんど何もすることができますが、彼らはなどの機能Tcl_SetResultTcl_SetObjResult、のいずれかを使用した結果を返すために、彼らは、関連する例外コードを含むintを返すことがあります。通常有用なものはTCL_OK(例外なし)とTCL_ERROR(ものが間違っている)です。これはC APIであるため、C++の例外は許可されていません。

コマンドの実装にC++のインスタンスメソッドを使用することはできますが、その間にバインド関数があることを前提としています。特に、関数はClientDataの値(実際にはvoid*のエイリアスで、これはでCのAPIはほとんどです)をキャストしてインスタンスポインタを取得し、そのメソッドを呼び出します。これは少量のコードです。


コンパイルでは、適切なライブラリ(または必要に応じてライブラリ)とリンクするDLLを作成するだけです。拡張機能は通常、スタブライブラリとのリンクを推奨しますが、1台のマシンで開発してテストするだけでは必要ありません。しかし、Tcl DLLとリンクしている場合は、そのDLLを使用するtclshにコードがロードされるようにしてください。スタブライブラリは、その強力なバインディングを取り除き、かなり強力なABI安定性を提供しますが、設定する作業はもう少しです。それらを有効にするには正しいCマクロを定義する必要があり、初期化関数で余分なAPI呼び出しを行う必要があります。

私は既にC++コードのコンパイルとリンクを知っていると仮定します。私はあなたにそれをする方法を教えませんが、もしあなたが助けを必要とするならば、Stack Overflowに他の質問があります。

コードを使用していますか?拡張のために、それだけで基本的にです:

# Dynamically load the DLL and call the init function 
load /path/to/your.dll 

# Commands are all present, so use them 
NewCommand 3 

いくつかの余分な手順が離れて、​​それはまさにそのDLLであるという事実からしてそうDLLを使用するコードを抽象化し、適切なTclパッケージにDLLを回すために後でありしかし、あなたは物事がより多く働くまで、心配するものではありません。

+0

@JoselitoSあなたのサンプルは非常に多くの詳細が欠落しているので、理解するのは本当に難しいです。あなたの質問を編集してそこに情報を入れてください。 (ここのコメントは、あなたが書くことができる程度に非常に限られています;それは完全な議論ではなく、_comments_のためです) –

+0

はい!あなたの答えは私を助けてくれました。私はそれに取り組んでおり、それはすべての人に便利であるために数日で質問を改善するだろう – JoselitoS

+0

私は質問を改正した、私はそれが今よりよく理解できることを願って – JoselitoS

関連する問題