SWIG - 为函数创建一个typemap,其中包含四个传递bytearray的参数

时间:2012-07-25 14:57:15

标签: java c++ byte swig

这是问题的后续问题How to use a ByteBuffer return from C++ to Java - 我将承认Flexo迄今为止的无情支持 - 我想我还没有得到类型图的悬念...... :-(

我有一个带有四个参数的C函数,如下所示,其中第三个和第四个参数通过引用传递

extern "C" int foo(const char* passByValText, const int passbyValLen, 
             unsigned char* retTextByRef, int *retTextLen) 

Calling Java Wrapper函数需要看起来像这样

int foo(String passByValText, int passbyValLen, byte[] retBuf, SWIGTYPE_p_int retTextLen);

或者它可能是

int foo(String passByValText, int passbyValLen, ByteBuffer retBuf, SWIGTYPE_p_int retTextLen);

我可以为我写的一个类型图分享道歉 - 但基本上这可能会让事情更加困惑......所以我保持这个清晰的名单..

下面是c侧的示例代码

extern "C" int foo (const char* passByValText, const int passbyValLen, char *retTextByRef, int *retTextLen){
    // binary value stuffed in the retTextByRef. In real program I compute this
    unsigned char someText[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x00};    
    memcpy(cipherText,someText,9);
    // I set the length of the value I stuffed into the buffer in c program
    *cipherLen=9;
return 0;

}

调用此c函数的Java程序

class Caller{
    public static void main(String[] args) {

    //Define the parameter to pass by reference!!
    SWIGTYPE_p_int retTextLen=MYMODULE.new_intp();

    //Create a Java Wrapper Instance 
    JavaWrapClass myWrap=new JavaWrapClass();

    StringBuffer sBuf = new StringBuffer(50);
    int retTextLenVal=0;
    myWrap.foo("PASSED-STRING-BY-VALUE", 24, sBuf, retTextLen);
    retTextLenVal= MYMODULE.intp_value(retTextLen);
    System.out.println("JAVA :: got length "+ retTextLenVal);
    System.out.println("JAVA :: got BUFFER "+ sBuf);
    }
}

非常感谢!!!

1 个答案:

答案 0 :(得分:1)

我使用以下标题进行测试:

static int foo(const char *passByValText, const int passByValLen,
               unsigned char *retTextByRef, int *retTextLen) {
  *retTextLen = passByValLen;
  if (retTextByRef) {
    memcpy(retTextByRef, passByValText, passByValLen);
  }
  return NULL == retTextByRef;
}

然后我将最简单的(例如最少自定义的类型映射)SWIG接口放在一起,我可以合理地包装这个函数:

%module test

%{
#include "test.h"
%}

%apply (char *STRING, size_t LENGTH) { (const char *passByValText, const int passByValLen) };
// Use String instead of byte[] for input as requested in Q:
%typemap(jstype) (const char *passByValText, const int passByValLen) "String"
%typemap(javain) (const char *passByValText, const int passByValLen) "$javainput.getBytes()"

%include <arrays_java.i>

// Force unsigned char array to be byte[] in Java:
%apply signed char[]  { unsigned char *retTextByRef };

%include <typemaps.i>

// Use the OUTPUT typemap - it passes an array with only one element
// could also use cpointers.i if you prefer
%apply int *OUTPUT { int *retTextLen };

%include "test.h"

最终将函数foo公开为一个带有三个输入的函数 - 输出数组为Stringbyte[],输出数为int[] { {1}}。

这让我写了:

int

测试时按预期工作。 arrays_java.i中的类型映射拒绝public class run { public static void main(String[] argv) { System.loadLibrary("test"); byte arr[] = new byte[100]; int sz[] = {100}; test.foo("Hello world", arr, sz); System.out.println(new String(arr, 0 , sz[0])); } } 数组,因此我编写的示例中的null不能用于查询输出大小。

如果您想使用if而不是StringBuffer,最简单的解决方案是使用byte[]在Java中生成重载:

%pragma