我有一个java回调函数,我想传递给C ++包装器,然后将它传递给C / C ++函数。
我该怎么做?
我认为包装器必须创建某种类型的C ++ lambda函数或沿着这些线来解析参数。
修改
以下是C中的回调签名。我将在java中实现这些。 (至少其中一些)
typedef struct ASIOCallbacks
{
void (*bufferSwitch) (long doubleBufferIndex, ASIOBool
void (*sampleRateDidChange) (ASIOSampleRate sRate);
long (*asioMessage) (long selector, long value, void* message, double* opt);
ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);
} ASIOCallbacks;
BTW:永远不会使用ASIOTime * params。
我在C函数中设置了回调。这是路径...
Java将回调传递给C ++包装器。 C ++包装器将它们传递给C函数来设置回调。
答案 0 :(得分:0)
我想你已经在C ++代码中的某个地方取消了JVM和将承载你的java函数的JNI环境:
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface
... // initialisation of these
让我们看看第一个例子:
您的 java 函数将类似于:
public class Callback {
public static void bufferSwitch (long index, ASIOBool b);
}
我猜你已经有了像Java一样实现的ASIOBool类型。如果不是,你必须这样做。
现在您可以编写 C ++包装器:
class Callback {
public:
static void bufferSwitch (long index, ASIOBool b);
...
};
void Callback::bufferSwitch (long index, ASIOBool b) {
jclass cls = env->FindClass("Callback"); // loads the Java class
if (cls==nullptr)
throw exception("Java class not found");
jmethodID mid = env->GetStaticMethodID(cls, "bufferSwitch","(JLASIOBool;)V");
if (mid==nullptr)
throw exception("Java method with appropriate signature not found");
// primitive types can be passed by value
// but for the other we must build an object
jclass cls2 = env->FindClass("ASIOBool"); // loads the Java class
if (cls2==nullptr)
throw exception("Java class not found");
jmethodID ctor = env->GetMethodID(cls2, "<init>", "()V");
if (ctor==nullptr)
throw exception("Java class constructor not found");
jobject jb = env->NewObject(cls2, ctor);
// ... to do: you have to initialize the Java ASIOBool object with the C++ ASIOBool components
// so if it's only a bool, better use the fundamental java type Boolean
// to avoid building a java object from C++
env->CallStaticVoidMethod(cls2, mid, (jlong)index, jb); // FINALLY WE CAN CALL !
env->DeleteLocalRef(jb); // tell the java garbage collector that we no longer use the tmp object
}
请注意,对于用作参数的每个Java对象(也称为基本类型),您必须提供签名。 fundamental types are coded作为一封信。其他类型/类以L开头,后跟完整的类名和半列。对于出现在包中的类,您必须指定全名(例如:&#34; Ljava / lang / String;&#34;对于java字符串)。
要了解详情:C++ JNI tutorial和C JNI tutorial。