2010-05-06 71 views
0

我想使用swig为复杂对象生成只读包装器。我想要包装的对象将永远存在,而我将读取它。我也只会在对象存在的时候使用我的包装,因此我不需要SWIG的任何内存管理。热摆脱在swig包装内存分配/释放?

对于以下痛饮接口:

%module test 

%immutable; 
%inline 

%{ 
    struct Foo 
    { 
     int a; 
    }; 

    struct Bar 
    { 
     int b; 
     Foo f; 
    }; 
%} 

我将有一个包装里面会有大量的垃圾在产生的接口和做无用功,这将在我的情况下降低性能。
的酒吧类生成的Java包装将是这样的:

public class Bar { 
    private long swigCPtr; 
    protected boolean swigCMemOwn; 

    protected Bar(long cPtr, boolean cMemoryOwn) { 
    swigCMemOwn = cMemoryOwn; 
    swigCPtr = cPtr; 
    } 

    protected static long getCPtr(Bar obj) { 
    return (obj == null) ? 0 : obj.swigCPtr; 
    } 

    protected void finalize() { 
    delete(); 
    } 

    public synchronized void delete() { 
    if (swigCPtr != 0) { 
     if (swigCMemOwn) { 
     swigCMemOwn = false; 
     testJNI.delete_Bar(swigCPtr); 
     } 
     swigCPtr = 0; 
    } 
    } 

    public int getB() { 
    return testJNI.Bar_b_get(swigCPtr, this); 
    } 

    public Foo getF() { 
    return new Foo(testJNI.Bar_f_get(swigCPtr, this), true); 
    } 

    public Bar() { 
    this(testJNI.new_Bar(), true); 
    } 

} 

我不需要“swigCMemOwn”字段在我的包装,因为它始终将是错误的。与此字段相关的所有代码也都是无用的。

也有在本地代码不必要的逻辑:

SWIGEXPORT jlong JNICALL Java_some_testJNI_Bar_1f_1get(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { 
    jlong jresult = 0 ; 
    struct Bar *arg1 = (struct Bar *) 0 ; 
    Foo result; 

    (void)jenv; 
    (void)jcls; 
    (void)jarg1_; 
    arg1 = *(struct Bar **)&jarg1; 
    result = ((arg1)->f); 
    { 
    Foo * resultptr = (Foo *) malloc(sizeof(Foo)); 
    memmove(resultptr, &result, sizeof(Foo)); 
    *(Foo **)&jresult = resultptr; 
    } 
    return jresult; 
} 

我不需要这些调用malloc和的memmove。

我想强迫swig解决这两个问题,但不知道如何。可能吗?

回答

2

要做到这一点,有必要编写结构类型的自定义typemaps,像这样的:

%typemap(javabody) SWIGTYPE %{ 
    private long swigCPtr; 

    protected $javaclassname(long cPtr) { 
    swigCPtr = cPtr; 
    } 
%} 

%typemap(jtype, nopgcpp="1") SWIGTYPE * "long" 
%typemap(javaout) SWIGTYPE { 
    long cPtr = $jnicall; 
    return new $javaclassname(cPtr); 
    } 

%typemap(javaout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) { 
    long cPtr = $jnicall; 
    return (cPtr == 0) ? null : new $javaclassname(cPtr); 
    } 

%typemap(out) SWIGTYPE %{ 
    *($&1_ltype*)&$result = &$1; 
%} 

%typemap(javadestruct) SWIGTYPE "" 

%typemap(javaclassmodifiers) SWIGTYPE "public final class" 
%nodefaultctor; 
%nodefaultdtor; 
%immutable;