SWIG Преобразование беззнаковых символов * в 20-байтовую буферную структуру Java - PullRequest
0 голосов
/ 30 ноября 2011

У меня есть функция C (composeKey), у которой есть входной параметр без знака char * ("ключ").На стороне C «ключ» должен быть пустой 20-байтовой структурой буфера.Я предполагаю, что короткий массив Java размером 20 будет правильной структурой Java для передачи «ключевого» параметра composeKey, но я не уверен.Может быть, мне нужен байт [20].Если это так, какая модификация файла интерфейса SWIG необходима для генерации Java-метода composeKey с коротким [] в качестве входных данных для параметра «ключ»?

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

1 Ответ

1 голос
/ 30 ноября 2011

Решение вашей конкретной проблемы

На самом деле 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]);

Если вы вызовете func из Java с массивом неправильного размера, вы получитеIndexOutOfBoundsException исключение, сгенерированное для вас автоматически кодом, который генерирует SWIG.


Общее решение

В этом конкретном случае "arrays_java.i" уже предоставляет подходящую карту типов.В более общем случае это работает, предоставляя SWIG карту типов для unsigned char [ANY] (буквально пишите ANY в синтаксисе карт типов SWIG).Затем создается экземпляр для конкретных значений вместо 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 ...
...