一千萬個為什麽

搜索

在swig包裝器中擺脫內存分配/解除分配的熱點?


我想使用swig為復雜對象生成只讀包裝器。我想要包裝的對象將始終存在,而我將閱讀它。而且我只會在對象存在時使用我的包裝器,因此我不需要SWIG的任何內存管理。

對於以下swig界面:

%module test

%immutable;
%inline

%{
    struct Foo
    {
        int a;
    };

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

我將有一個包裝器,它會在生成的接口中產生大量垃圾,並且做無用的工作會降低我的性能。
為Bar類生成的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解決這兩個問題,但不知道如何。可能嗎?

最佳答案

為此,有必要為結構類型編寫自定義類型映射,如下所示:

%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;

轉載註明原文: 在swig包裝器中擺脫內存分配/解除分配的熱點?

猜你喜歡