• 使用swig从c/c++代码生成java/python/R/php...代码


    我们项目中有一个协议打包模块,c++写的。需要移植到java和python上,不想重写,就使用了一个叫swig(http://swig.org/)的工具,从c++代码直接生成了java/python代码。推荐一下。

    几点感受:
    (1)swig支持的语言还是很多的,可以从c/c++生成java/python/php/R/ruby等等一堆语言,这个工具有20多年的历史了。其他语言的支持程度不了解,我们生成的java/python代码是直接用到了项目中;
    (2)swig是跨平台的,linux/windows上我都成功的生成/运行过,相对来说linux上更简单;
    (3)swig并不直接生成java/python代码,而是先将原始的c/c++编译成动态库so/dll,然后再生成包装层的java/python代码,使用时直接调用包装层代码即可(java的包装层就是jni代码)。这是因为各语言的特性不一致,比如c/c++中的模板、嵌套类、指针、数据类型等,在java/python中不一定完整支持。
    (4)类型映射,需要将c/c++中的数据类型映射到目标语言中的类型。普通类型一般不需要处理,但char*映射到java时比较麻烦,默认是映射到string,但我们是打包协议,需要映射到byte[],于是使用typemap做了处理。
    (5)c++中的模板、重载、namespace等特性是支持的,但嵌套类目前不支持。

    ---------------------------------

    update:

    关于java的jni,朋友有如下观点,这里记下作为参考:

    第一,JNI程序两种内存之间的同步问题和指针处理经常会导致JVM崩溃。

    第二,频繁的两种内存之间的数据交换导致性能下降,于是本机代码的优势就没有了。

    我们的东西,要求尽量不使用本机代码,而是通过配置程序来使得pure java代码支持各个平台。 

    JNI应用里面,这里我们假定是JAVA和C/C++,两边使用完全不同的内存模型。C/C++部分是我们自己来分配和释放内存,内存地址在地址空间里面是固定不变的;而JAVA部分是我们分配内存,JVM来回收内存,内存地址在地址空间是浮动的,这个差别决定了很多事情。

    第一。两边的内存使用之前要先锁定,然后获取,进行处理,然后拷贝,最后解锁,以此来防止出现无效地址问题。这种做法在JVM需要进行内存回收的时候会导致程序暂停问题,同时降低了程序的运行效率。另外,在锁定的内存足够大的时候,连JVM的内存回收都会出现问题,因此本机代码的实现上必须做些工作,来保证一次不锁定太多的内存,或者JVM那边要给出很大的内存设置。

    第二。对上述过程的稍不注意,就会出现非法指针问题而导致某端的崩溃,这里崩溃的不一定是JVM,C/C++部分也一样会完蛋的。

    另外还有一个问题,那就是两边的异常处理,数据以及数据结构的定义上的差别,使得这点要非常小心,因为它同样涉及数据转换问题。

    因此除非我们有大量成熟的C/C++程序,转换成本很高,或者不用本机代码就没办法解决,否则一般不推荐使用JNI,因为它好处没有麻烦多。

    ---------------------------------

    update:

    需要注意的是,swig是GPL license的,而我们公司禁止使用该授权的工具,因此在项目结项时还是重新写了一份java/python的协议打包模块。真悲催!

  • 相关阅读:
    DevExpress控件开发常用要点(项目总结版)
    DevExpress BarManager 部分用法
    DevExpress LookUpEdit和ComboBoxEdit部分用法
    DevExpress GridControl 部分用法
    DevExpress 中 WaitForm 使用
    DevExpress汉化(WinForm)
    DevExpress 使用 XtraTabbedMdiManager 控件以 Tab样式加载 Mdi窗体并合并 RibbonControl 解决方案
    DevExpress 关于 GridView 表格编辑中 点击其他按钮里导致 值未取到处理
    DevExpress 中 在做全选的全消功能的时候 加快效率
    DevExpress后置代码中初始化SQL数据源的方法
  • 原文地址:https://www.cnblogs.com/chutianyao/p/2840914.html
Copyright © 2020-2023  润新知