SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构
Posted
技术标签:
【中文标题】SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构【英文标题】:SWIG Convert unsigned char* to 20 byte buffer Java structure 【发布时间】:2011-11-30 00:35:36 【问题描述】:我有一个 C 函数(composeKey),它有一个输入 unsigned char* 参数(“key”)。在 C 端,“key”需要是一个空的 20 字节缓冲区结构。我假设一个大小为 20 的 Java 短数组将是传递 composeKey 的“key”参数的正确 Java 结构,但我不确定。也许我需要一个字节[20]。如果这是正确的,那么需要修改什么 SWIG 接口文件来生成带有 short[] 作为“key”参数输入的 composeKey Java 方法?
C Function:
int composeKey(const void* secret, int secret_len, unsigned char* key, int length);
【问题讨论】:
【参考方案1】:解决您的具体问题
Java 在其类型系统中并没有真正区分 short[20]
和(例如)short[21]
。不过,您可以非常简单地做一些非常明智的事情,让key
的长度对于 SWIG 来说总是 20 是显而易见的:
%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++ 中的模板),然后您可以使用 $1_size
在您的类型图中访问 ANY
的特定值并提供填充大小的代码看起来(为简洁起见,省略了一些 JNI 细节)大致如下:
if (GetArrayLength(arg) != $1_size)
// Code to throw a Java Exception ...
然后在生成的包装器中变成:
if (GetArrayLength(arg) != 20)
// Code to throw a Java Exception ...
【讨论】:
以上是关于SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构的主要内容,如果未能解决你的问题,请参考以下文章
SWIG 将 const unsigned char example[] 包装到 Java byte[] 作为参数
TypeError:在方法“...”中,使用 swig 模块时类型为“unsigned char const *”的参数 1
Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数