【Android NDK 开发】JNI 方法解析 ( JNIEXPORT 与 JNICALL 宏定义作用 )

举报
韩曙亮 发表于 2022/01/10 23:54:53 2022/01/10
【摘要】 文章目录 I . JNIEXPORT 与 JNICALL 宏定义II . JNIEXPORT 与 JNICALL 宏定义说明 ( Windows 平台 )III . JNIEXPORT 与 JNI...



I . JNIEXPORT 与 JNICALL 宏定义



JNIEXPORT 与 JNICALL 是 JNI 中定义的两个宏 :


① Windows 平台宏定义 :

#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_

#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall

typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;

#endif /* !_JAVASOFT_JNI_MD_H_ */

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

② Linux 平台宏定义 :

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

  
 
  • 1
  • 2
  • 3

JNIEXPORT 在 Windows 与 Linux 分别对应不同的宏定义 ;


2 . JNIEXPORT 宏定义作用 :


Windows 中如果需要生成动态库 , 并且需要将该动态库交给其它项目使用 , 需要在方法前加入特殊标识 , 才能 在外部 程序代码中 调用该 DLL 动态库中定义的方法 ;


① Windows 平台 : 需要将方法 返回值 之前加入 __declspec(dllexport) 标识 ;

② Linux 平台 : 需要将方法 返回值 之前加入 attribute ((visibility (“default”))) 标识 ;

该声明的作用是保证在本动态库中声明的方法 , 能够在其他项目中可以被调用 ;


3 . JNICALL宏定义作用 :


① Windows JNICALL : JNICALL 被定义为 __stdcall , __stdcall 是一种函数调用参数的约定 , 在 Windows 中调用函数时 , 该函数的参数是以 栈 的形式保存的 , 栈 中元素是后进先出的 , __stdcall 表示参数是从右到左保存的 ;

__stdcall 用于 定义 函数入栈规则 ( 从右到左 ) , 和 堆栈清理规则 ;


② Linux JNICALL : JNICALL 没有进行定义 , 直接置空 ; 在 Linux 中可以不用写 JNIEXPORT 和 JNICALL 宏 ;



II . JNIEXPORT 与 JNICALL 宏定义说明 ( Windows 平台 )



1 . Windows 平台宏定义说明 :


① JNIEXPORT 宏定义 : Windows 平台定义 " #define JNIEXPORT __declspec(dllexport) " , 在编译器编译时 , 会使用 "__declspec(dllexport) " 代替 JNIEXPORT ;

② JNICALL 宏定义 : Windows 平台宏定义 " #define JNICALL __stdcall " , 在编译时 , 使用 " __stdcall " 代替 JNICALL ;


2 . JNIEXPORT 和 JNICALL 宏替换分析 ( Windows 平台 ) :


① 使用 JNIEXPORT 和 JNICALL 的原始方法 :

extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_jni_Main_jniTest
	(JNIEnv* env, jobject instance, jint i, jstring s_) {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

② 编译过程中宏替换后的代码 :

extern "C"
__declspec(dllexport) void __stdcall
Java_kim_hsl_jni_Main_jniTest
	(JNIEnv* env, jobject instance, jint i, jstring s_) {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5


III . JNIEXPORT 与 JNICALL 宏定义说明 ( Linux 平台 )



1 . Linux 平台宏定义说明 :


① JNIEXPORT 宏定义 : Linux 平台定义
#define JNIEXPORT attribute ((visibility (“default”))) ,
在编译器编译时 , 会使用 "__declspec(dllexport) " 代替 JNIEXPORT ;

② JNICALL 宏定义 : Linux 平台 该宏定义 为空 ;


2 . JNIEXPORT 和 JNICALL 宏替换分析 ( Linux 平台 ) :


① 使用 JNIEXPORT 和 JNICALL 的原始方法 :

extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_jni_Main_jniTest
	(JNIEnv* env, jobject instance, jint i, jstring s_) {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

② 编译过程中宏替换后的代码 :

extern "C"
__attribute__ ((visibility ("default"))) 
void 
Java_kim_hsl_jni_Main_jniTest
	(JNIEnv* env, jobject instance, jint i, jstring s_) {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/104072587

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。