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

标签 java c++ swig

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

公开通过非常量引用传递的 std::string 参数的最简单方法是什么?

由于 typemaps.i 和 const std::string&s 公开为 java.lang.String,我有通过引用公开为 Java 数组的原语,谢谢到 std_string.i。但是非常量 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

更新:我找到了解决方案,如下所述。然而,这比几秒钟更费力。我仍然有兴趣了解简单的方法。

最佳答案

我能找到的最好方法是编写我自己的类型映射。我一直希望得到一些简单的 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 };

生成的绑定(bind)如下所示:

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::string 的值从 UTF-8 转换回 Java 字符串。

关于java - SWIG:如何包装 std::string&(通过引用传递的 std::string),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3753495/

相关文章:

Java 等价于 Python 的 "Got value: %s"% 变量?

java - 自动顺序显示图像

c++ - 如何比较 sfml 中的位置?

c++ - 多个应用程序如何使用同一个网络端口?

c++ - Visual C++ : Using nested templates, 是否可以将 ">>"而不是 ">>"标记为错误?

c++ - Lua + SWIG 猴子补丁

python - 如何使用 SWIG 在 python 中扩展模板化的 c++ 类以允许 [] 运算符

java - 如何从字符串图像中获取像素 RGB 值? .get 不适用于 imageLoader(处理中)

java - 如何使用 java.nio.ByteBuffer 从 C++ 返回到 Java

java - File.mkdirs() 创建目录而不是文件