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

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

2回复

如何在C代码中回调Java方法(而不是C中的jni方法)?

我遇到一个问题,即如何在C方法中回调 Java方法,该C方法不同于JNI生成C方法。 在参数列表中不包括JNIEnv和JObject参数。 如何解决它或其他解决方法。
2回复

JNI:从JVM到C ++的回调无法运行

我从C ++程序启动JVM。 C ++代码: 然后我需要从Java调用的C ++函数: Java代码: 当我运行C ++程序时,JVM正确启动,但是在它显示“ Calling callBackIntoNative()”之后,将出现以下接受: 你能帮忙吗?
1回复

从C ++类崩溃到Java的JNI回调

我正在尝试在Android上使用JNI从C ++类调用Java函数。 我进行了搜索,但没有找到确切的案例。 我可以从Java调用c ++库中的方法,但是在执行相反操作时会遇到问题。 我已经把它弄乱了两天,浪费时间,所以有谁比我更能帮助我? 完整目标:保留JNIEnv,或者仅保留Jav
1回复

从Java调用C ++应用程序通过JNI调用c ++回调

我有一个需要与Java库接口的C ++应用程序。 我想从Java端收到通知,因此需要回调到C ++应用程序。 我发现了很多关于从C ++调用Java函数的例子(这是一个简单的部分),并从Java调用从Java导出的C / C ++函数。 到目前为止,我发现的一切都是如何从Java应用程
1回复

JVM在attachCurrentThread JNI回调调用上崩溃

希望你一切顺利。 我在C中有一个JNI实现,其中一个C函数附加到当前JVM线程并回调Java方法,该方法实际上在attachCurrentThread()函数调用时使JVM崩溃。 我的实现基于链接中给出的答案保持对JNIEnv环境的全局引用 线程创建部分,它将侦听套接字连接以接受事
1回复

如何在jni中创建CBTHook,然后在回调函数中调用Java函数?

更新(13/02/23):单独测试了Hook,它可以工作。 问题是,除非您将控制台与其关联,否则您不能在.dll中使用printf 。 我改为将每个printf替换为fprintf ,并将输出写入日志文件。 更新(13/02/22):以正确的方式初始化了变量clazz 。 如
1回复

JNI回调上的运行时错误

从本地代码进行JNI回调时,我面临一个致命错误: SIGSEGV .. 以及对该问题重要的代码: 如果我注释掉回调行( jniEnv->CallVoidMethod ... ),就没有问题,一切都会按预期进行。 问题在于实际的回调,甚至在某些JVM上也很陌生,它的工
1回复

从本机线程通过JNI回调时,Java线程泄漏

简介:在本机创建的线程上从本机代码调用Java时,我看到Java线程泄漏。 (2014年2月11日更新:我们将此作为对Oracle的支持请求提出。现在Oracle已经在Java 7更新45上证实了它。它只影响64位Linux(可能还有Mac)平台:32位Linux不受影响) 。 (2
2回复

如何将java函数指针传递给c ++本机代码

我想从java(android)代码调用本机c ++方法,并将java函数作为参数传递,因此我将能够将函数指针保存在c ++代码中,并从本机代码中激活它。 我选择使用匿名类在java中实现函数指针,我从java调用本机函数如下: } 如何让swig / jni知道第3个pa
2回复

Java Invocation API:从java代码中调用C函数

我有一个C(navive)程序和一个带main()方法的jar文件。 从我的本机程序,我正在初始化JVM,并调用main()方法。 我对此没有任何问题,一切都很好。 但后来我想从我的java代码中回调一个C函数。 C函数在与创建JVM的模块相同的模块中的本机代码中定义。 标题是自动