JNI 中的宏定义

一、宏定义

宏定义可以理解为就是定义一个常量或一个函数,实现复用,易于统一维护和修改。

// 不带参数的宏定义
#define MAX 10

// 带参宏定义
#define M(y) y * y + 3 * y

// 宏调用
k = M(5);

二、JNIEXPORTJNICALL

JNIEXPORTJNICALL 实际上是 JNI 中定义的两个宏,它们在 WindowsLinux 分别有不同的定义。

// 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_ */
// Linux 系统
#define JNIIMPORT
#define JNIEXPORT  __attribute__ ((visibility ("default")))
#define JNICALL
三、JNIEXPORTJNICALL 宏定义作用
  • JNIEXPORT 宏定义作用
    如果我们的程序需要生成动态链接库 , 并且要把该动态链接库交给其它程序使用, 那么就需要在函数前加入特殊标识 , 才能在其它程序代码中调用该动态链接库中定义的函数 。动态链接库在 Windows 系统和 Linux 系统中通常分别是 .dll文件 和 .so文件。
    那么根据不同系统中 JNIEXPORT 宏定义的不同,在预编译时就会进行对应的宏替换。
  • JNICALL 宏定义作用
    • Windows 系统中 JNICALL 宏定义为 __stdcall , __stdcall 是一种函数调用约定 , 因为当程序编译为本地机器码由 CPU 执行时,CPU无法明确知道每个函数应该怎么传参,于是提供了栈结构来支持参数传递,但当调用函数有多个参数时,参数应该按照怎样的顺序入栈,然后函数调用完栈又应该由谁来清理,针对这两个问题,出现了一些函数调用约定,__stdcall 就是其中的一种,__stdcall 修饰的函数在调用时参数都是从右向左依次被压入到栈中,函数调用完在返回前由被调用函数自己负责清理堆栈。

    • Linux 系统中 JNICALL 没有进行定义 , 直接置空, 因此在 Linux 中是可以不用写 JNICALL 宏的 。

四、JNIEXPORTJNICALL 宏替换

  • Windows 系统 :
// 使用 JNIEXPORT 和 JNICALL 的原始方法
extern "C"
JNIEXPORT void JNICALL Java_bytecode_NativeTest_sayWithMsgAndNum(JNIEnv *jniEnv, jobject obj, jstring msg, jint num) {
    // 函数体
}
// 预编译过程中宏替换后的方法
extern "C"
__declspec(dllexport) void __stdcall Java_bytecode_NativeTest_sayWithMsgAndNum(JNIEnv *jniEnv, jobject obj, jstring msg, jint num) {
    // 函数体
}
  • Linux 系统
// 使用 JNIEXPORT 和 JNICALL 的原始方法
extern "C"
JNIEXPORT void JNICALL Java_bytecode_NativeTest_sayWithMsgAndNum(JNIEnv *jniEnv, jobject obj, jstring msg, jint num) {
    // 函数体
}
// 预编译过程中宏替换后的方法
extern "C"
__attribute__ ((visibility ("default"))) void Java_bytecode_NativeTest_sayWithMsgAndNum(JNIEnv *jniEnv, jobject obj, jstring msg, jint num) {
    // 函数体
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JNI编程 JNI是一种本地编程接口。它允许运行在JAVA虚拟机中的JAVA代码和用其他编程语言,诸如C语言、C+...
    微尘_8957阅读 3,265评论 0 0
  • 1.C语言预处理理论 1.1、由源码到可执行程序的过程 (1)源码.c→(预处理)→预处理过的.i源文件→(编译)...
    嵌入式Linux小白阅读 4,245评论 0 0
  • JNI-Java Native Interface,是Java平台提供的一个特性,通过编写JNI函数实现Java代...
    李牙刷儿阅读 3,633评论 0 2
  • 谈谈亲子阅读和交流的好处。 读原著,是需要勇气的,也需要一定能力。 午休,叫了一个班上学习相对比...
    分明鱼阅读 3,704评论 2 5
  • 南疆挂职,顾名思义,从新疆非南疆地区组织干部赴南疆三地州进行挂职,简单的讲就是解决南疆干部力量不足的问题,干部也抱...
    逆袭爽风阅读 4,897评论 0 0