• 使用SWIG实现C/C++与其他语言间的互相调用 zz


     
    为了运行速度,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等多种语言
     

    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1714946

  • 相关阅读:
    了解Whitehorse
    更新排行榜说明
    一个从Microsoft Word发表Blog文章的工具
    首页"进入我的博客"可以正常使用了
    ADO.NET: Close()与Dispose() 的讨论
    向大家致歉
    折腾了我一个下午及吃晚饭时间的问题
    [转帖]ASP.NET服务器端异步Web方法
    关于增加“收藏”功能的设想
    Mono 0.30发布了
  • 原文地址:https://www.cnblogs.com/cutepig/p/925436.html
Copyright © 2020-2023  润新知