SWIG const char * setter

时间:2016-10-19 13:18:58

标签: java c++ swig setter

我使用SWIG编写用C ++编写的共享库的Java包装器。在库中有一个类似于此的联合:

union Union{
    int f_int;
    double f_double;
    bool f_bool;
    const char* f_string;
    MyObject* f_my_object;
};

我将此联合包装起来,SWIG会为联盟中的所有字段生成getter和setter。

但是当我运行SWIG时,我收到了警告:

Warning 451: Setting a const char * variable may leak memory.

我理解为什么会这样,因为SWIG文档中有一个解释:http://www.swig.org/Doc1.3/SWIG.html(第5.5.4章)。

我的问题是:在包装const char *类型时是否有任何技巧可以避免内存泄漏。我必须处理这种类型,因为我无法对库源进行任何更改。

我会感谢你的帮助。

修改

我知道如何解决问题,但我不确定它是否正确。但是关于这个问题的第一个细节:

SWIG为const char * union成员setter生成C代码,如下所示:

SWIGEXPORT void JNICALL Java_example_exJNI_Union_1f_1string_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) {
  Union *arg1 = (Union *) 0 ;
  char *arg2 = (char *) 0 ;

  (void)jenv;
  (void)jcls;
  (void)jarg1_;
  arg1 = *(Union **)&jarg1; 
  arg2 = 0;
  if (jarg2) {
    arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
    if (!arg2) return ;
  }
  {
    if (arg2) {
      arg1->f_string = (char const *) (new char[strlen((const char *)arg2)+1]);
      strcpy((char *)arg1->f_string, (const char *)arg2);
    } else {
      arg1->f_string = 0;
    }
  }
  if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
}

问题在于:

arg1->f_string = (char const *) (new char[strlen((const char *)arg2)+1]);

正如SWIG文件所说:

  

当声明类型为const char *的变量时,SWIG仍会生成用于设置和获取值的函数。但是,默认行为不会释放先前的内容(导致可能的内存泄漏)。

所以我认为我应该强制SWIG生成如下所示的C代码:

SWIGEXPORT void JNICALL Java_example_exJNI_Union_1f_1string_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) {
  Union *arg1 = (Union *) 0 ;

  static std::string* arg2_ = new std::string();

  const char *arg2 = (const char *) 0 ;

  (void)jenv;
  (void)jcls;
  (void)jarg1_;
  arg1 = *(Union **)&jarg1; 
  arg2 = 0; 
  if (jarg2) {
    arg2 = (const char *)jenv->GetStringUTFChars(jarg2, 0);
    if (!arg2) return ;
  }
  {
    if (arg2) {
      &(arg2_)->assign(arg2);
      jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
      arg1->f_string = arg2_->c_str();
    } else {
      arg1->f_string = 0;
    }
  }
}

是否解决了内存泄漏问题?我想是的,但也许我忽视了一些事情。

我想知道如何强制SWIG改变这个,只有这个功能看起来像我想要的那样。我应该使用某些类型图或其他东西吗?

0 个答案:

没有答案