SWIG:如何包装std :: string&(通过引用传递的std :: string)

我正在使用SWIG从Java访问C ++代码。

公开由非const引用传递的std :: string参数的最简单方法是什么?

感谢stma_string.i,我将原型通过引用传递给Java数组,这要归功于typemaps.i和const std::string& s公开为java.lang.String 。 但是非const std :: string&作为不透明指针类型暴露为SWIGTYPE_p_std__string

当前:

 // C++ method -> // Java wrapper of C++ method void foo( int & i ) -> public void foo( int[] i ); // OK void bar( const std::string & s ) -> public void bar( String s ); // OK void baz( std::string & s ) -> public void baz( SWIGTYPE_p_std__string s ); // :( 

期望:

 void foo( int & i ) -> public void foo( int[] i ); // OK void bar( const std::string & s ) -> public void bar( String s ); // OK void baz( std::string & s ) -> public void baz( String[] s ); // OK 

更新 :我找到了一个解决方案,如下所述。 但是,它需要花费更多精力而不是几秒钟。 我仍然有兴趣听到简单的方法。

我能找到的最好方法是编写自己的typemap。 我一直希望有一些简单的SWIG指令。

如果其他人需要这个,我就是这样做的。 请记住,我不是SWIG专家。

首先,您需要定义一些要应用于std :: string和arguments的类型映射。 您只需要定义一次。 (注意:某些配置中可能还需要其他类型图。)

 %typemap(jni) std::string *INOUT, std::string &INOUT %{jobjectArray%} %typemap(jtype) std::string *INOUT, std::string &INOUT "java.lang.String[]" %typemap(jstype) std::string *INOUT, std::string &INOUT "java.lang.String[]" %typemap(javain) std::string *INOUT, std::string &INOUT "$javainput" %typemap(in) std::string *INOUT (std::string strTemp ), std::string &INOUT (std::string strTemp ) { if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return $null; } if (JCALL1(GetArrayLength, jenv, $input) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return $null; } jobject oInput = JCALL2(GetObjectArrayElement, jenv, $input, 0); if ( NULL != oInput ) { jstring sInput = static_cast( oInput ); const char * $1_pstr = (const char *)jenv->GetStringUTFChars(sInput, 0); if (!$1_pstr) return $null; strTemp.assign( $1_pstr ); jenv->ReleaseStringUTFChars( sInput, $1_pstr); } $1 = &strTemp; } %typemap(freearg) std::string *INOUT, std::string &INOUT "" %typemap(argout) std::string *INOUT, std::string &INOUT { jstring jStrTemp = jenv->NewStringUTF( strTemp$argnum.c_str() ); JCALL3(SetObjectArrayElement, jenv, $input, 0, jStrTemp ); } 

接下来,对于这样的每个 C ++参数模式……

 void foo( std::string & xyzzy ); void bar( std::string & xyzzy ); void baz( ..., std::string & xyzzy, ... ); 

…您使用此SWIG指令应用上面的类型映射:

 %apply std::string &INOUT { std::string & xyzzy }; 

生成的绑定如下所示:

 public void foo( java.lang.String[] xyzzy ); public void bar( java.lang.String[] xyzzy ); public void baz( ..., java.lang.String[] xyzzy, ... ); 

它们每个都需要一个单元素的String数组。 在输入时,第一个元素可以为null。 如果为非null,则将其转换为UTF-8 std :: string值并传递给C ++函数。 退出时,引用传递的std :: string的值将从UTF-8转换回Java String。