c++ 调用system 不显示黑框_阿里架构师讲解不一样的JVM——你真的了解JNI的运行机制吗...

我们经常会遇见 Java 语言较难表达,甚至是无法表达的应用场景。比如我们希望使用汇编语言(如 X86_64 的 SIMD 指令)来提升关键代码的性能;再比如,我们希望调用 Java 核心类库无法提供的,某个体系架构或者操作系统特有的功能。

在这种情况下,我们往往会牺牲可移植性,在 Java 代码中调用 C/C++ 代码(下面简述为C 代码),并在其中实现所需功能。这种跨语言的调用,便需要借助 Java 虚拟机的 JavaNative Interface(JNI)机制。

关于 JNI 的例子,你应该特别熟悉 Java 中标记为native的、没有方法体的方法(下面统称为 native 方法)。当在 Java 代码中调用这些 native 方法时,Java 虚拟机将通过 JNI,调用至对应的 C 函数(下面将 native 方法对应的 C 实现统称为 C 函数)中。

public class Object {    public native int hashCode();}

举个例子,Object.hashCode方法便是一个 native 方法。它对应的 C 函数将计算对象的哈希值,并缓存在对象头、栈上锁记录(轻型锁)或对象监视锁(重型锁所使用的monitor)中,以确保该值在对象的生命周期之内不会变更。

一、native方法的链接

在调用 native 方法前,Java 虚拟机需要将该 native 方法链接至对应的 C 函数上。

链接方式主要有两种。第一种是让 Java 虚拟机自动查找符合默认命名规范的 C 函数,并且链接起来。

事实上,我们并不需要记住所谓的命名规范,而是采用javac -h命令,便可以根据 Java程序中的 native 方法声明,自动生成包含符合命名规范的 C 函数的头文件。

举个例子,在下面这段代码中,Foo类有三个 native 方法,分别为静态方法foo以及两个重载的实例方法bar。

package org.example;public class Foo {    public static native void foo();    public native void bar(int i, long j);    public native void bar(String s, Object o);}

通过执行javac -h . org/example/Foo.java命令,我们将在当前文件夹(对应-h后面跟着的.)生成名为org_example_Foo.h的头文件。其内容如下所示:

/* DO NOT EDIT THIS FILE - it is machine generated */#include /* Header for class org_example_Foo */#ifndef _Included_org_example_Foo#define _Included_org_example_Foo#ifdef __cplusplusextern "C" {    #endif    /** Class:     org_example_Foo* Method:    foo* Signature: ()V*/    JNIEXPORT void JNICALL Java_org_example_Foo_foo    (JNIEnv *, jclass);    /** Class:     org_example_Foo* Method:    bar* Signature: (IJ)V*/    JNIEXPORT void JNICALL Java_org_example_Foo_bar__IJ    (JNIEnv *, jobject, jint, jlong);    /** Class:     org_example_Foo* Method:    bar* Signature: (Ljava/lang/String;Ljava/lang/Object;)V*/    JNIEXPORT void JNICALL Java_org_example_Foo_bar__Ljava_lang_String_2Ljava_lang_Object_2    (JNIEnv *, jobject, jstring, jobject);    #ifdef __cplusplus}#endif#endif

这里我简单讲解一下该命名规范。

首先,native 方法对应的 C 函数都需要以Java_为前缀,之后跟着完整的包名和方法名。由于 C 函数名不支持/字符,因此我们需要将/转换为,而原本方法名中的符号,则需要__转换为_1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值