java - 将函数的前 2 个参数之外的所有参数传递给另一个函数

标签 java c jit ffi calling-convention

我计划编写一个 Java FFI 库,它将使用 DynASM在运行时生成 FFI 蹦床,而不是通过 libffi 执行解释调用。

至少在最初,我不打算支持按值传递/返回复合类型。 C 数据结构将通过直接的 ByteBuffer 在 Java 中创建。指针将通过 sun.misc.Unsafe 获取和取消引用,并表示为 Java long 值。

JNI 调用的工作原理如下:

JNIEXPORT t JNICALL my_c_func(JNIEnv *env, jobject *self, jlong arg);

问题是有两个不需要的参数。我想编写一个蹦床来删除这两个参数,然后调用实际的函数。在 Windows 系统上,它需要从 stdcall(由 Windows 上的 JNI 使用)转换为 stdcallcdeclthiscall。另外,DynASM 不支持动态寄存器分配。

问题实际上非常简单:我如何(在汇编中)将一个函数除了前两个参数之外的所有参数传递给另一个函数?在 C 中,我将生成一个函数,如下所示:

jlong my_function(JNIEnv* env, jobject obj, jlong val) {
   return called_function(val);
}

我正在尝试在汇编中执行此操作。 objc_msgsend 对 Objective-C 程序执行此操作,但据我所知,在宽松的许可证下没有实现。

最佳答案

我会回答两个不同的问题,因为我不确定你到底在问什么,我不知道你是否在问:

  • JNI 函数中的两个额外参数要从 Java 代码调用,或者
  • JNI 函数中的两个额外参数可从 C/C++ 代码调用。

所以我给你两个答案:

假设Java调用

我认为您认为 JNIEnv *env, jobject *self 是两个不需要的参数,但它们是必需的。这些参数对您来说是透明的,因为它们是由 JNI 管理的。

让我解释一下。在 Java 中,您想要调用 native 函数,例如:

private static native void myFunc(String param1);

为了在 Java 和 native C/C++ 代码之间建立桥梁,您需要调用一个 native 函数,其签名为

JNIEXPORT void JNICALL Java_MyClass_myFunc(JNIEnv *, jclass, jstring);

如您所见,有两个参数 JNIEnv *jclass 是通过 JNI 管理的,但您的 native 函数只有一个 String > 映射到第三个 jstring JNI native 调用的参数。

假设 C/C++ 调用

如果您尝试从 C/C++ 代码的另一部分调用此函数,那么您就错了,因为您不能。该函数必须从 JNI 调用,以便正确传递对 JNI 环境的引用并为调用对象提供自引用。

如果您想这样做,那么您将必须创建另一个独立于 JNI 的函数,该函数可以从 JNI 函数和其他 C/C++ 函数调用。

通过这种方式,您可以将逻辑与 View 解耦,考虑到 JNI 调用可以访问逻辑的 View 。

希望有帮助。

关于java - 将函数的前 2 个参数之外的所有参数传递给另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32929757/

相关文章:

c - 对字符数组进行冒泡排序

c - 海龟用 openGl 绘制分形

java - 借助JIT,程序运行时间越长,速度就越快?

Java NullPointerException,游戏开发,图像对象问题

java - 如何对弹力球实现声明?

Ubuntu 中的 JavaFX Scene Builder 路径

c++ - 使用导入的 makefile 将 Qt Creator .config 添加到 .h

java - Java中的JIT编译是如何将动态编译好的指令加载到内存中的?

c# - 为什么在通过反射更改静态只读字段后,该只读字段的输出是旧的?

Java - 如何在使用特殊符号后删除单词