JNI для C с использованием Swig & trouble с обратным вызовом функции-указателя

у нас есть функция C в одной из библиотек, которые загружаются в java, которая принимает указатель на функцию

функции, как показано ниже

typedef char int8 typedef unsigned short uint16 uint32 poll_broadcasts(void *(pfn)(int8*,uint16)); 

В C он используется как ниже

 void handle_broadcasts( int8 *broadcast, uint16 length ) uint32 a = poll_broadcasts( (void*(*)(int8*,uint16)) handle_broadcasts ) 

Но когда вы используете Swig для создания JNI-оболочки, он создает следующее определение для poll_broadcast

 public static long poll_broadcasts(SWIGTYPE_p_f_p_char_unsigned_short__p_void pfn) { return TestJNI.poll_broadcasts(SWIGTYPE_p_f_p_char_unsigned_short__p_void.getCPtr(pfn)); } 

В соответствии с ответом
Как написать файл .i для переноса обратных вызовов в Java или C #

Пробовал ниже

test.h

 void * data; typedef void* (*callback_handle_broadcast_t)(int8*, uint16); static callback_handle_broadcast_t handle_broadcast; static void set_handle_broadcast(callback_handle_broadcast_t cb, void *userdata) { handle_broadcast = cb; data = userdata; } 

Интерфейсный файл Swig Test.i

 %module Test %include "cpointer.i" %include "carrays.i" %include "various.i" %include "arrays_java.i" %pointer_functions(int, intp); %pointer_functions(char, charp); %include "arrays_java.i" %include "typemaps.i" %{ #include  #include "test.h" struct callback_data { JNIEnv *env; jobject obj; }; void java_callback(int8* arg1, uint16 arg2, void *ptr) { struct callback_data *data = ptr; const jclass callbackInterfaceClass = (*data->env)->FindClass(data->env, "BroadcastCallback"); assert(callbackInterfaceClass); const jmethodID meth = (*data->env)->GetMethodID(data->env, callbackInterfaceClass, "handle", "([C)V"); assert(meth); jcharArray charArr = (*data->env)->NewCharArray(data->env, arg2); (*data->env)->CallVoidMethod(data->env, data->obj, meth, (jcharArray)charArr); } %} %typemap(jstype) callback_handle_broadcast_t cb "BroadcastCallback"; %typemap(jtype) callback_handle_broadcast_t cb "BroadcastCallback"; %typemap(jni) callback_handle_broadcast_t cb "jobject"; %typemap(javain) callback_handle_broadcast_t cb "$javainput"; %typemap(in,numinputs=1) (callback_handle_broadcast_t cb, void *userdata) { struct callback_data *data = malloc(sizeof *data); data->env = jenv; data->obj = JCALL1(NewGlobalRef, jenv, $input); JCALL1(DeleteLocalRef, jenv, $input); $1 = java_callback; $2 = data; } %include "test.h" , %module Test %include "cpointer.i" %include "carrays.i" %include "various.i" %include "arrays_java.i" %pointer_functions(int, intp); %pointer_functions(char, charp); %include "arrays_java.i" %include "typemaps.i" %{ #include  #include "test.h" struct callback_data { JNIEnv *env; jobject obj; }; void java_callback(int8* arg1, uint16 arg2, void *ptr) { struct callback_data *data = ptr; const jclass callbackInterfaceClass = (*data->env)->FindClass(data->env, "BroadcastCallback"); assert(callbackInterfaceClass); const jmethodID meth = (*data->env)->GetMethodID(data->env, callbackInterfaceClass, "handle", "([C)V"); assert(meth); jcharArray charArr = (*data->env)->NewCharArray(data->env, arg2); (*data->env)->CallVoidMethod(data->env, data->obj, meth, (jcharArray)charArr); } %} %typemap(jstype) callback_handle_broadcast_t cb "BroadcastCallback"; %typemap(jtype) callback_handle_broadcast_t cb "BroadcastCallback"; %typemap(jni) callback_handle_broadcast_t cb "jobject"; %typemap(javain) callback_handle_broadcast_t cb "$javainput"; %typemap(in,numinputs=1) (callback_handle_broadcast_t cb, void *userdata) { struct callback_data *data = malloc(sizeof *data); data->env = jenv; data->obj = JCALL1(NewGlobalRef, jenv, $input); JCALL1(DeleteLocalRef, jenv, $input); $1 = java_callback; $2 = data; } %include "test.h" 

Интерфейс Java BrodcastCallback.java

 public interface BroadcastCallback { //public void handle(String broadcast); public void handle(char[] broadcast); } 

Внедрить интерфейс

 class BtCallback implements BroadcastCallback { @Override public void handle(char[] broadcast) { LOG.debug("Broadcast callback handled: " + broadcast.length); } } 

Наконец, когда используется

 BroadcastCallback cb = new BtCallback(); Test.set_handle_broadcast(cb, null); Test.poll_broadcasts(Test.getHandle_broadcast()); 

Ошибка компиляции, но когда программа запускается, и poll_broadcasts вызывает указатель функции передачи сообщений (внутри C), переданный из java, он выходит из строя с EXCEPTION_ACCESS_VIOLATION.

Похоже, что он должен что-то делать с помощью int8 * arg функции, но не может понять

кто-нибудь, пожалуйста, помогите.