2012-02-26 13 views
1

まとめspidermonkey埋め込みでjs-ctypesを提供するにはどうすればよいですか?

私はSpiderMonkeyの「シェル」アプリケーションではJavaScriptオブジェクトのctypesを作成するために使用するコードの上に見てきましたが、私はより少なくより初心者Cプログラマです。現代のビルドシステムによって放出されるさまざまなレベルの狂気のため、私は実際にプログラムを所望の機能と結びつけるコードまたはコマンドを追跡するようには見えない。


method.madness

のMozillaのDevによるこのJS-ctypesの実装は素晴らしい付加です。その構想以来、スクリプティングは、主に、より厳密で堅牢なアプリケーションに対する制御を発揮するために使用されてきました。 SpiderMonkeyプロジェクトへのjs-ctypesの登場により、JavaScriptは立ち上がり、マイクロソフトのVB6などの様々な由緒あるアプリケーション開発言語によって設定された「バー」を上回る高速のアプリケーション開発言語としての本格的なオブジェクトとしてカウントされます。


開始しますか?

私はこの設定でSpiderMonkeyのを建て:./configureを--enable-ctypesの--with-システムNSPRの実行が成功に続いて

:& &は

JSをインストールしますが、作品をシェル作りをそのシェルでグローバルctypes javascriptオブジェクトが動作確認されました。

/* Populate the global object with the ctypes object. */ 
    if (!JS_InitCTypesClass(cx, global)) 
     return NULL; 
    /* 

私がしてコンパイル:G ++ $(How to embed the JavaScript Engine -MDNで上場最初のソースから取得したコードを使用した作業

は、私は66行に次のコードを挿入して、オブジェクトをctypesはJavaScriptをインスタンス化しようとする試みを行いました。/JS-config設定--cflags --libs)HELLO.CPP -oハロー

それは、いくつかの警告をコンパイル:

hello.cpp: In function ‘int main(int, const char**)’: 
hello.cpp:69:16: warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null] 
hello.cpp:80:20: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
hello.cpp:89:17: warning: NULL used in arithmetic [-Wpointer-arith] 

しかし、あなたはアプリケーションシートを実行しますN:

./hello: symbol lookup error: ./hello: undefined symbol: JS_InitCTypesClass 

また

JS_InitCTypesClassがのextern 'DIST// jsapi.h含む' で宣言が、関数がそれ自身を含む 'ctypesの/ CTypes.cpp' に存在していますヘッダ 'CTypes.h'を編集し、ある時点でいくつかのコマンドで 'make'を実行してyeild './CTypes.o'にコンパイルします。前に述べたように、私はCコードの初心者ではないので、ここで何をすべきか分かりません。

js-ctypesオブジェクトを埋め込みで機能させる一般的な例を示したり、指示を与えたりしてください。

答えて

1

問題点:ほとんどのプラットフォームディストリビューターは、コードデベロッパーの推奨事項を無視しています。したがって、js-ctypesは、ライブラリをホストするすべてのシステムではないにしても、ほとんどの場合mozjs185では有効になりません。これは、あなたが整理するためのいくつかの問題を残します。あなたは--enable-ctypesのを使用して構成し、--with-のsytem-NSPR makeが続いた後、make install

あなたはおそらくlibmozjs185の2つのバージョンがあります(最後のコマンドのためにrootになる必要がある場合があります)した後

.soをシステムにインストールします。 1つはctypesを有効にしたもの(/ usr/local/libにあります)とctypesを有効にしていないもの(/ usr/libにあります)です。

質問に応じて、ライブラリ ctypesをリンクしたいとします。コンパイラに-L/usr/local/lib -lnspr4 -lmozjs185を指定することでこれが実現します。それは大丈夫にコンパイルされます。しかし、アプリケーションが実行されると、osライブラリ・ローダーは見つかったライブラリの最初のインスタンスをロードします。残念ながら、これはおそらく/ usr/libにあるライブラリであり、このバージョンではctypesが有効になっていない可能性があります。ここであなたはこの[解決済みの]問題にぶつかるでしょう:g++ Undefined Symbol Error using shared library

最終行はこれです:同じライブラリの複数のバージョンが問題を引き起こしています。したがって、spidermonkeyの埋め込みにjs-ctypesを提供する最善の方法は、複数のプラットフォームのlibaryローダーを扱うためのライブラリを作成する場合を除いて、mozjs185のctypes対応静的バージョンをプログラムにリンクするか、独自の(mozjs185 )これは私はあなたが++グラムで、これらのパラメータを使用する必要があります静的リンクを実行するにはSpiderMonkey Build Documentation - MDN

@上で非常に詳細にカバーされています: -lnspr4 -lpthread -lmozjs185-1.0は、あなたが構築していることを提供して正しく開発パッケージをインストールしました。これは、spidermonkey埋め込みにjs-ctypesを提供するための「最良の」(プラットフォームに依存しない)方法です。これにより、アプリケーションのサイズが少なくとも3.5 MB増加しますが、デバッグバージョンをビルドした場合、それは15倍以上になる可能性があります。

+0

それは1つの気高い旅行でした! –

+0

-lol 'libary'私はそこにその1つを残しています!私は子供だったので、それを聞いていない。 –

1

ハック

すでに結合があるため、ヘッダーファイルでの条件付き定義だけでなく、散乱libとヘッダの場所を失敗していたように私には発生していました。十分に...私はコマンドラインでJS_HAS_CTYPESを定義しようとしましたが、それがうまくいくかどうかは確かに十分ではありませんでした。

私はSpiderMonkeyシェルに独自のmakefileがあり、キャプチャしようとしている機能に既にアクセスできていると判断しました。js.cppの名前をjs.cpp.tmpに変更し、場所は、ほとんど働いた。

ファイルがコンパイルされていて、アプリケーション実行時に実行時リンクエラーがスローされませんでしたが、コード(JSNativeObject 'ctypes)はJS_InitCTypesClassにほぼ完全に失敗しました。私のリンクエラーが長い間忘れられていたのを見て、私はすぐにコンパイルコードをスワイプすることができるかどうかを確認するためにmakeの出力を調べました...私たちはビンゴを持っています!


コンパイル

は元の標的にシェル/ js.cppを復元した後、私はSpiderMonkeyのルートのソースディレクトリにHELLO.CPPを移動した相対パスを修正し始めましたmakefileによって作成され、アプリケーションに存在感や依存性を明らかに持たない構造体の削除を実行します。

次のコマンドが動作バイナリをレンダリングするように見えるが、著者はこのリストの正確性や完全性について何らの親和性を与えることはできません。上記

c++ -o hello.o -c -Idist/system_wrappers_js -include config/gcc_hidden.h \ 
-DEXPORT_JS_API -DOSTYPE=\"Linux3.2\" -DOSARCH=Linux -I. -Idist/include \ 
-Idist/include/nsprpub -I/usr/include/nspr -fPIC -fno-rtti \ 
-fno-exceptions -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth \ 
-Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wcast-align \ 
-Wno-invalid-offsetof -Wno-variadic-macros -Werror=return-type -pedantic \ 
-Wno-long-long -fno-strict-aliasing -pthread -pipe -DNDEBUG -DTRIMMED -Os \ 
-freorder-blocks -fomit-frame-pointer -DJS_HAS_CTYPES -DMOZILLA_CLIENT \ 
-include js-confdefs.h -MD -MF .deps/hello.pp hello.cpp; 

c++ -o hello -fno-rtti -fno-exceptions -Wall -Wpointer-arith \ 
-Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy \ 
-Wno-non-virtual-dtor -Wcast-align -Wno-invalid-offsetof \ 
-Wno-variadic-macros -Werror=return-type -pedantic \ 
-Wno-long-long -fno-strict-aliasing -pthread -pipe -DNDEBUG \ 
-DTRIMMED -Os -freorder-blocks -fomit-frame-pointer hello.o \ 
-lpthread -Wl,-rpath-link,/bin -Wl,-rpath-link,/usr/local/lib \ 
-Ldist/bin -Ldist/lib -L/usr/lib -lplds4 -lplc4 -lnspr4 \ 
-lpthread -ldl editline/libeditline.a libjs_static.a -ldl; 

二つのコマンドは、ルートソースディレクトリに保存された「mkhello」という名前の実行可能なシェルスクリプトに入れました。私はそれが2段階のコンパイル方法で収集することができるものから、

。どのような理由で私はわかりませんが、説明は非常に教育的です。思考?

EDIT「two stage compilation method」の説明については、下記のコメントを参照してください。


コード:HELLO.CPP

/* 
* This define is for Windows only, it is a work-around for bug 661663. 
*/ 
#ifdef _MSC_VER 
# define XP_WIN 
#endif 

/* Include the JSAPI header file to get access to SpiderMonkey. */ 
#include "jsapi.h" 


/* The class of the global object. */ 
static JSClass global_class = { 
    "global", JSCLASS_GLOBAL_FLAGS, 
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, 
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, 
    JSCLASS_NO_OPTIONAL_MEMBERS 
}; 

/* The error reporter callback. */ 
void reportError(JSContext *cx, const char *message, JSErrorReport *report) 
{ 
    fprintf(stderr, "%s:%u:%s\n", 
      report->filename ? report->filename : "<no filename=\"filename\">", 
      (unsigned int) report->lineno, 
      message); 
} 

int main(int argc, const char *argv[]) 
{ 
    /* JSAPI variables. */ 
    JSRuntime *rt; 
    JSContext *cx; 
    JSObject *global; 

    /* Create a JS runtime. You always need at least one runtime per process. */ 
    rt = JS_NewRuntime(8 * 1024 * 1024); 
    if (rt == NULL) 
     return 1; 

    /* 
    * Create a context. You always need a context per thread. 
    * Note that this program is not multi-threaded. 
    */ 
    cx = JS_NewContext(rt, 8192); 
    if (cx == NULL) 
     return 1; 
    JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); 
    JS_SetVersion(cx, JSVERSION_LATEST); 
    JS_SetErrorReporter(cx, reportError); 

    /* 
    * Create the global object in a new compartment. 
    * You always need a global object per context. 
    */ 
    global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); 
    if (global == NULL) 
     return 1; 

    /* 
    * Populate the global object with the standard JavaScript 
    * function and object classes, such as Object, Array, Date. 
    */ 
    if (!JS_InitStandardClasses(cx, global)) 
     return 1; 

    /* Populate the global object with the ctypes object. */ 
    if (!JS_InitCTypesClass(cx, global)) 
     return NULL; 
    /* 

    /* Your application code here. This may include JSAPI calls 
    * to create your own custom JavaScript objects and to run scripts. 
    * 
    * The following example code creates a literal JavaScript script, 
    * evaluates it, and prints the result to stdout. 
    * 
    * Errors are conventionally saved in a JSBool variable named ok. 
    */ 
    char *script = "ctypes.open"; 
    jsval rval; 
    JSString *str; 
    JSBool ok; 
    const char *filename = "noname"; 
    uintN lineno = 0; 

    ok = JS_EvaluateScript(cx, global, script, strlen(script), 
          filename, lineno, &rval); 
    if (rval == NULL | rval == JS_FALSE) 
     return 1; 

    str = JS_ValueToString(cx, rval); 
    printf("%s\n", JS_EncodeString(cx, str)); 

    /* End of your application code */ 

    /* Clean things up and shut down SpiderMonkey. */ 
    JS_DestroyContext(cx); 
    JS_DestroyRuntime(rt); 
    JS_ShutDown(); 
    return 0; 
} 

結論

$ ./mkhello 
# ... 
# error free garbage scrolls.... 
$ ./hello 
function open() { 
    [native code] 
} 

はSpiderMonkeyの埋め込みにJS-ctypesのを提供するために、この例では、次のとおり。これらの手順を順番に再作成する必要はありませんが、現在の観点からすることを強くお勧めします。

+0

これは答えですが、リンケージを知っている誰かが正しい答えを返す場合には、私はこれを最良の答えとして受け入れていません。 –

+0

「2段階コンパイル方法」:1段階がコンパイルされます。もう一つのリンク。 –

関連する問題