何时在 Android NDK 中使用 JNIEXPORT 和 JNICALL? [英] when to use JNIEXPORT and JNICALL in Android NDK?

查看:12
本文介绍了何时在 Android NDK 中使用 JNIEXPORT 和 JNICALL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写自己的 jni 资源.查看一些 ndk 示例,我发现他们经常使用这些宏 JNIEXPORT 和 JNICALL 后跟 java 包的名称这样的

I'm trying to write my own jni sources. Looking at some ndk samples, I found that they often use those macros JNIEXPORT and JNICALL follewed by the name of java package like this

JNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(JNIEnv * env, jobject obj, jobject bitmap, jlong​​ time_ms)

我用谷歌搜索了,但我不明白何时以及如何使用这些宏

I googled it but I can't understand when and how to use these macros

推荐答案

JNIEXPORT 和 JNICALL 定义在 NDK_ROOT/platforms/android-9/arch-arm/usr/include/jni.h 中.根据您的设置,此路径会有所不同,但大多相似.

JNIEXPORT and JNICALL are defined in NDK_ROOT/platforms/android-9/arch-arm/usr/include/jni.h. Depending on your setup this path will be different, but mostly similar.

#define JNIIMPORT
#define JNIEXPORT  __attribute__ ((visibility ("default")))
#define JNICALL

JNIEXPORT 用于使本地函数出现在构建的二进制文件(*.so 文件)的动态表中.它们可以设置为隐藏"或默认"(更多信息这里).如果这些函数不在动态表中,JNI 将无法找到调用它们的函数,因此 RegisterNatives 调用将在运行时失败.

JNIEXPORT is used to make native functions appear in the dynamic table of the built binary (*.so file). They can be set to "hidden" or "default" (more info here). If these functions are not in the dynamic table, JNI will not be able to find the functions to call them so the RegisterNatives call will fail at runtime.

值得注意的是,默认情况下,所有函数最终都在动态表中,因此任何人都可以很容易地反编译您的本机代码.每个函数调用都内置在二进制文件中,以防 JNI 需要找到它.这可以使用编译器选项 -fvisibility 进行更改.我建议大家将其设置为 -fvisibility=hidden 以确保您的代码安全,然后使用 JNIEXPORT 将函数标记为具有外部可见性.

It is worth noting that all functions end up in the dynamic table by default, so anyone could decompile your native code quite easily. Every function call is built into the binary just in case JNI needs to find it. This can be changed using the compiler option -fvisibility. I would recommend everyone sets this to -fvisibility=hidden to keep your code secure, and then use JNIEXPORT to flag functions as having external visibility.

使用 strip 命令只是删除调试符号,动态表是独立的.玩 objdump 看看一个人可以从你的 .so 文件中得到多少.

Using the strip command just removes the debug symbols, the dynamic table is separate. Have a play with objdump to see how much a person could get out of your .so files.

我们最近被这个绊倒了,希望这对某人有所帮助.

We recently got tripped up by this, hope this helps someone.

我们使用自定义构建系统,因此默认情况下可以为其他构建设置设置可见性选项.this SO answer中提供了更多信息.

We use a custom build system, so the visibility option may be set by default for other build setups. More information is available in this SO answer.

这篇关于何时在 Android NDK 中使用 JNIEXPORT 和 JNICALL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆