Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Swig&;函数指针回调出现问题_Java_C_Java Native Interface_Function Pointers_Swig - Fatal编程技术网

Java 使用Swig&;函数指针回调出现问题

Java 使用Swig&;函数指针回调出现问题,java,c,java-native-interface,function-pointers,swig,Java,C,Java Native Interface,Function Pointers,Swig,我们在java中加载的一个库中有一个C函数,它接受一个函数指针 功能定义如下 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*(*)(i

我们在java中加载的一个库中有一个C函数,它接受一个函数指针

功能定义如下

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\u广播创建以下定义

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));
  }
根据

在下面试用

测试h

Swig接口文件Test.i

实现接口

最后使用时

并没有编译错误,但当程序运行并且poll_broadcasts调用从java传递的句柄广播函数指针(在C中)时,它会崩溃,出现异常访问冲突

看起来它与函数的int8*arg有关,但无法理解


有人请帮忙。

当你播放
uint32民意测验时(void*(pfn)(int8*,uint16)),您是指函数指针吗?如果是,则应改为
uint32 poll_广播(void(*pfn)(int8*,uint16))是,它是一个接受函数指针作为参数的函数。我想通过一个java方法回调来使用JNI轮询broacast。我们不能修改poll_广播。在回答帖子中提到的问题时取得了一些成功,但运气不好,程序在运行时崩溃。
typedef void*(*callback\u handle\u broadcast)(int8*,uint16):您是否希望函数的返回类型为
void
void*
?最初尝试使用void,但定义与Swig创建的定义不匹配。根据轮询广播定义,java回调必须映射到
typedef void*(*callback\u handle\u broadcast)(int8*,uint16)
。在C语言中,虽然它的工作方式与我写的一样,
poll\u广播((void*(*)(int8*,uint16))handle\u广播)
它调用handle\u广播函数,并且它有返回类型
void
。您有
数据的定义吗?您正在
set\u handle\u broadcast
中访问它,但我似乎在任何地方都找不到它的定义?
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;
}
%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 <assert.h>

#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"
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());