我能找到的最好的方法是编写自己的类型图。我一直希望有一些琐碎的SWIG指令。
如果其他人需要这个,这是我是如何做到的。请记住,我不是SWIG专家。
首先,您需要定义一些要应用于 std::string& 参数的类型映射。您只需定义一次。(注意:在某些配置中可能需要其他类型映射。
%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<jstring>( 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, ... );
它们都需要一个单元素字符串数组。在输入时,第一个元素可能为空。如果非空,则将其转换为 UTF-8 std::string 值并传递给C++函数。退出时,通过引用传递的 std::字符串的值将从 UTF-8 转换回 Java 字符串。