栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

C std :: string作为带有SWIG的Java中的输出参数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C std :: string作为带有SWIG的Java中的输出参数

假设您希望在不修改现有头文件的情况下包装它,就想到了两种方法。给定我用于测试的头文件:

#include <string>inline bool method2(const std::string & name, const std::string & alias, std::string & resurnValue, std::string & returnType) {  resurnValue = name;  returnType = alias;  return true;}

包装它的最简单方法是使用

%inline
创建一个将所有输出包装为一种类型的重载:

%module test%include <std_string.i>%{#include "test.h"%}%inline %{  struct Method2Result {    bool b;    std::string s1;    std::string s2;  };  Method2Result method2(const std::string& in1, const std::string& in2) {    Method2Result ret;    ret.b = method2(in1,in2,ret.s1,ret.s2);    return ret;  }%}// Optional: don't wrap the original form of method2 at all:%ignore method2;%include "test.h"

这适用于:

public class run {  public static void main(String[] args) {    System.loadLibrary("test");    Method2Result ret = test.method2("foo", "bar");    System.out.println(ret.getB() + " - " + ret.getS1() + ", " + ret.getS2());  }}

我怀疑您可能曾经使用过

std::pair
boost::tuple
使用过,
%template
但是包装
boost::tuple
是不平凡的,因此您可以为成员命名一个适当的名称,库的用户将理解这些适当的名称,而不是just
first
second
,而不必使用
%rename
它而变得比仅在其中编写自定义结构更冗长
%inline


另外,SWIG提供了可用于

%apply
创建输出argumnet的OUTPUT类型映射。它们被包装为1个元素的数组-
传递数组的语义与输出参数的语义匹配。不幸的是
std::string
,typemaps.i中没有适合的代码,因此我们必须编写自己的代码。理想情况下,我将重用该
OUTPUT_TYPEMAP
文件中的宏,并稍稍修改了argout类型映射,但是它
#undef
无法实现。幸运的是,在这种情况下,只需复制和修改是相当简单的:

%module test%{#include "test.h"%}%typemap(jstype) std::string& OUTPUT "String[]"%typemap(jtype) std::string& OUTPUT "String[]"%typemap(jni) std::string& OUTPUT "jobjectArray"%typemap(javain)  std::string& OUTPUT "$javainput"%typemap(in) std::string& OUTPUT (std::string temp) {  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");  }  $1 = &temp;}%typemap(argout) std::string& OUTPUT {  jstring jvalue = JCALL1(NewStringUTF, jenv, temp$argnum.c_str());   JCALL3(SetObjectArrayElement, jenv, $input, 0, jvalue);}%apply  std::string& OUTPUT { std::string & resurnValue }%apply  std::string& OUTPUT { std::string & returnType }%include "test.h"

可以像这样使用:

public class run {  public static void main(String[] args) {    String[] out1 = new String[1];    String[] out2 = new String[1];    boolean retb = test.method2("foo", "bar", out1, out2);    System.out.println(retb + " - " + out1[0] + ", " + out2[0]);  }}

这两个都经过测试并在我的系统上工作。对于这种情况,我喜欢这种

%inline
方法。(如果是成员函数,则
%extend
改为使用)。在一般情况下,可以使用OUTPUT类型映射,而无需编写任何额外的代码。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/498281.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号