1. 程式人生 > >使用SWIG實現C/C++與其他語言間的互相呼叫

使用SWIG實現C/C++與其他語言間的互相呼叫

  為了執行速度,java, C#, ruby等語言可能會呼叫C/C++寫的函式或者類,但直接寫很麻煩,必須遵循各種語言訂立的規範,以jni為例要匯出一個函式給java用,你必須在函式定義前寫上JNIEXPORT,對於那些早已存在的程式碼,這樣就麻煩了,而且相同的程式碼如果要給ruby用,又得按照擴充套件Ruby的規定去重新定義這些函式。並且不能將C++定義的類直接拿來用 但SWIG能很方便,很自然的將C/C++程式碼轉換給這些語言用。 要使用swig需要到www.swig.org去下載這個工具。 以ruby為例,講講用法。 首先下載ruby, 我的是1.8.5, 執行configure.bat生成Makefile檔案,再用nmake命令生成config.h檔案和需要的靜態庫 用vs2005新建一個動態庫工程 //Test.h class TestRuby { public:    TestRuby();
    void print(); }; void testFun(); //Test.cpp #include "test.h" #include<iostream> using namespace std; TestRuby::TestRuby() {     cout<<"Test::Test/n"; } void TestRuby::print() {     cout<<"hello swig/n"; } void testFun() {     cout<<"testFun/n"; } //Test.i %module test %{
    #include "test.h" %} %include "test.h" 注意include前的是%,昨天看成#,害得白忙了半天,汗 建立一個空白檔案test_wrap.cxx 設定好環境變數,執行 swig c++ -ruby test.i (也可以在專案屬性中的自定義生成步驟中定義這些命令,具體見MSDN) 這時會更新test_wrap.cxx檔案 自動生成ruby呼叫C函式需要的一些東東 如: SWIGEXPORT void Init_test(void) {  size_t i;  SWIG_InitRuntime();  mTest = rb_define_module("Test"
);
 SWIG_InitializeModule(0);  for (i = 0; i < swig_module.size; i++) {     SWIG_define_class(swig_module.types[i]);  }  SWIG_RubyInitializeTrackings();  cTestRuby.klass = rb_define_class_under(mTest, "TestRuby", rb_cObject);  SWIG_TypeClientData(SWIGTYPE_p_TestRuby, (void *) &cTestRuby);  rb_define_alloc_func(cTestRuby.klass, _wrap_TestRuby_allocate);  rb_define_method(cTestRuby.klass, "initialize", VALUEFUNC(_wrap_new_TestRuby), -1);  rb_define_method(cTestRuby.klass, "print", VALUEFUNC(_wrap_TestRuby_print), -1);  cTestRuby.mark = 0;  cTestRuby.destroy = (void (*)(void *)) free_TestRuby;  cTestRuby.trackObjects = 0;  rb_define_module_function(mTest, "testFun", VALUEFUNC(_wrap_testFun), -1); } 在附加包含目錄中引入ruby.h所在的那個路徑 在連結器中把需要的庫附加進去,我這裡連結的是msvcrt-ruby18.lib 編譯,生成dll 寫個ruby檔案測試 require 'test' t = Test::TestRuby.new() t.print Test.testFun 正確輸出 Test::Test Hello swig testFun 如果要把這個程式碼給java,或C#用只要改變一下swig的命令引數,然後再編譯一次就行了,異常方便 Swig不支援C++所以特性,但常用的特性都支援,不太影響使用。 Swig支援C#, java, Lua, Ruby, Perl, Python, Tcl等多種語言