2010-05-06 72 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;