我有一个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;

顺便说一句:ASIOTime *参数将永远不会使用。 我在C函数中设置了回调。 这是路...

Java将回调传递给C ++包装器。 C ++包装器将它们传递给C函数以设置回调。

===============>>#1 票数:0

我想您已经在C ++代码中的某个地方调用了将托管Java函数的JVM和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对象(也称为基本类型),都必须提供签名。 基本类型编码为字母。 其他类型/类以L开头,后跟完整的类名和一个半列。 对于出现在包中的类,您必须指定全名(例如:对于Java字符串,为“ Ljava / lang / String;”)。

要了解更多信息: C ++ JNI教程C JNI教程

  ask by Caleb Merchant translate from so

未解决问题?本站智能推荐: