JNI之一:什么是JNI (Java Native Interface)

1 篇文章 0 订阅

在这里插入图片描述
JNI,即Java本地接口 (Java Native Interface),它是连接Java代码本地代码之间的桥梁,其中,本地代码可以是C,C++,Fortran等语言编写的。JNI允许我们在Java代码中调用本地代码,也允许本地代码调用Java代码。

我们都知道,在Java中存在本地方法(native method),这种方法用native关键字进行修饰。本地方法底层是用C/C++语言实现的。调用本地方法和调用普通的Java方法的语法一样。

Java代码会被编译成平台无关的字节码,而用C/C++编写的本地方法实现则不是编译成平台无关的格式,而是编译成平台相关共享链接库 (shared library),然后被加载进JVM中。在Windows系统中,共享链接库是.dll格式;在Linux系统中,共享链接库是.so格式。

这也就意味着,当我们的Java代码中用到本地方法后,就不能保证所编写Java程序的可移植性了,除非我们为所有的目标平台都编写一份本地代码实现。

既然本地代码会影响Java程序的可移植性,那么为什么还需要本地代码呢?原因如下:

  • Java应用需要依赖某些平台相关的特性。例如,Java中的线程底层实际上是基于操作系统内核线程的,不同操作系统内核线程的实现都不相同,因此Java线程的某些操作必须用本地方法来实现。
  • 性能原因。Java应用中的某些部分可能对性能和速度要求很高,这部分代码可以采用C/C++来编写。
  • 等等

一般来说,使用本地方法应该是我们的最后一个选择,不到万不得已的情况下并不推荐使用本地方法。

在本系列后续的文章中,将会介绍如何使用JNI编写代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的JNI C++代码示例,用于扫描蓝牙设备并发送数据: ``` #include <jni.h> #include <string> #include <iostream> #include <vector> #include <cstring> #include <unistd.h> #include <sys/socket.h> #include <bluetooth/bluetooth.h> #include <bluetooth/rfcomm.h> extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_scanAndSendData(JNIEnv *env, jobject /* this */) { std::string result = ""; // 扫描蓝牙设备 int max_attempts = 3; int attempts = 0; std::vector<std::string> addresses; while (addresses.empty() && attempts < max_attempts) { inquiry_info *ii = nullptr; int num_rsp = 0; int dev_id = hci_get_route(nullptr); int sock = hci_open_dev(dev_id); if (sock >= 0) { ii = static_cast<inquiry_info *>(malloc(255 * sizeof(inquiry_info))); num_rsp = hci_inquiry(dev_id, 8, 255, nullptr, &ii, IREQ_CACHE_FLUSH); if (num_rsp < 0) { perror("hci_inquiry"); } for (int i = 0; i < num_rsp; ++i) { char addr[19] = {0}; ba2str(&(ii+i)->bdaddr, addr); addresses.push_back(addr); } free(ii); ii = nullptr; close(sock); } ++attempts; sleep(1); } // 连接蓝牙设备并发送数据 if (!addresses.empty()) { for (const auto &address : addresses) { int fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); sockaddr_rc addr{}; addr.rc_family = AF_BLUETOOTH; addr.rc_channel = 1; str2ba(address.c_str(), &addr.rc_bdaddr); int status = connect(fd, reinterpret_cast<const sockaddr *>(&addr), sizeof(addr)); if (status == 0) { std::string message = "Hello, World!"; ssize_t bytes_sent = send(fd, message.c_str(), message.length(), 0); if (bytes_sent == -1) { perror("send"); } close(fd); } } result = "Data sent successfully!"; } else { result = "No Bluetooth device found."; } return env->NewStringUTF(result.c_str()); } ``` 这段代码使用了Linux系统的socket API和BlueZ库来进行蓝牙设备的扫描和数据传输。它首先尝试多次扫描蓝牙设备,如果发现了任何设备,就尝试连接并发送数据。如果没有找到任何设备,则返回错误消息。你需要根据你的具体情况对代码进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值