我有一个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);
答案 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 ...