SWIG将unsigned char *转换为20字节缓冲区Java结构

时间:2011-11-30 00:35:36

标签: swig

我有一个C函数(composeKey),它有一个输入unsigned char *参数(“key”)。在C端,“key”需要是一个空的20字节缓冲区结构。我假设一个大小为20的Java短数组将是传递composeKey的“关键”参数的正确Java结构,但我不确定。也许一个字节[20]是我需要的。如果这是正确的,那么生成使用short []作为“key”参数的输入的composeKey Java方法需要什么样的SWIG接口文件?

C Function:
int composeKey(const void* secret, int secret_len, unsigned char* key, int length);

1 个答案:

答案 0 :(得分:1)

解决您的具体问题

Java在其类型系统中并没有真正区分short[20]和(例如)short[21]。你可以做一些非常明智的事情,因为key的长度对于SWIG来说总是显而易见的:

%module test

%include "arrays_java.i"

int func(unsigned char key[20]);

这甚至可以在不直接更改函数的实际签名的情况下工作--SWIG可以包装它,但让包装的代码调用一个仍然非常明智地使用unsigned char*的函数:

%module test

%{
#include "header.h"
// fine even if it's func(unsigned char *key) in the header.
%}

%include "arrays_java.i"
int func(unsigned char key[20]);

如果您使用大小不合适的数组从Java调用func,您将获得由SWIG生成的代码自动抛出的IndexOutOfBoundsException异常。


一般解决方案

在这种特定情况下,"arrays_java.i"已经提供了合适的类型图。在更一般的情况下,这通过为SWIG提供unsigned char [ANY]的类型映射(在SWIG类型映射语法中字面写ANY)来工作。然后根据ANY(有点像C ++中的模板)对特定值进行实例化,然后使用ANY访问类型映射中的$1_size的特定值并提供代码为了简洁起见,大小被填入以寻找(一些JNI细节被省略)大致如下:

if (GetArrayLength(arg) != $1_size) {
    // Code to throw a Java Exception ...

然后在生成的包装器中变为:

if (GetArrayLength(arg) != 20) {
    // Code to throw a Java Exception ...