Java JNI开发时常用数据类型与C++中数据类型转换

简介: Java JNI开发时常用数据类型与C++中数据类型转换

JavaJNI开发时常用数据类型与C++中数据类型转换

常见的数据类型对应关系如下:

此外我们经常用String类型,它可以通过如下的API实现jstring到char*之间的相互转换constchar* szString = env-> GetStringUTFChars(jstring, 0);这种转换出来的char*类型数据,使用完之后一定要调用

env-> ReleaseStringUTFChars(jstring, szString);释放掉,不然会导致内存泄漏,如果忘记JVM会崩溃的。从C++中创建一个新的字符串然后返回的代码如下:

// create jstring
  jstring computerName = env->NewStringUTF(chRtn);
  return computerName;

其中chRtn是char数组类型的指针。

下面是一个Java通过JNI接口调用C++的Windows接口实现电脑名称和用户名称查询的例子,首先定义JNI接口类如下

package com.gloomyfish.jnidemo;
 
 
public class HelloJNI {
  
  public native int helloJNI(String name);
  
  public native String getComputerName();
  
  public native String getUserName();
  
  public native double calculateDistance(double x, double y);
  
  public static void main(String[] args) {
    System.loadLibrary("jnitest");
    HelloJNI happ = new HelloJNI();
    happ.helloJNI("gloomyfish");
    double sum = happ.calculateDistance(3, 4);
    String computerName = happ.getComputerName();
    String user = happ.getUserName();
    
    System.out.println("sum : " + sum);
    System.out.println("computer name : " + computerName);
    System.out.println("current user : " + user);
    System.out.println();
  }
}

C++中实现如下:

// jnitest.cpp : 定义 DLL 应用程序的导出函数。
//
 
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include "math.h"
#include "com_gloomyfish_jnidemo_HelloJNI.h"
 
JNIEXPORT jint JNICALL Java_com_gloomyfish_jnidemo_HelloJNI_helloJNI
(JNIEnv *env, jobject obj, jstring param) {
  // convert java string type to c++ char* type
  const char* name = env->GetStringUTFChars(param, 0);
  printf("%s %s\n", "Hello JNI, I am ", name);
  // release memory
  env->ReleaseStringUTFChars(param, name);
  // return 0;
  return 0;
}
 
JNIEXPORT jstring JNICALL Java_com_gloomyfish_jnidemo_HelloJNI_getComputerName
(JNIEnv *env, jobject obj) {
  // define the buffer size
  const int MAX_BUFFER_LEN = 500;
  TCHAR  infoBuf[MAX_BUFFER_LEN];
  DWORD  bufCharCount = MAX_BUFFER_LEN;
  GetComputerName(infoBuf, &bufCharCount);
 
  // conver to jstring
  printf("computer name : %ls\n", infoBuf);
  int nLen = WideCharToMultiByte(CP_ACP, 0, infoBuf, -1, NULL, 0, NULL, NULL);
  char* chRtn = new char[nLen];
  WideCharToMultiByte(CP_ACP, 0, infoBuf, -1, chRtn, nLen, NULL, NULL);
 
  // create jstring
  jstring computerName = env->NewStringUTF(chRtn);
  return computerName;
}
 
JNIEXPORT jstring JNICALL Java_com_gloomyfish_jnidemo_HelloJNI_getUserName
(JNIEnv *env, jobject obj) {
  // define the buffer size
  const int MAX_BUFFER_LEN = 500;
  TCHAR  infoBuf[MAX_BUFFER_LEN];
  DWORD  bufCharCount = MAX_BUFFER_LEN;
  GetUserName(infoBuf, &bufCharCount);
 
  // conver to jstring
  printf("current user : %ls\n", infoBuf);
  int nLen = WideCharToMultiByte(CP_ACP, 0, infoBuf, -1, NULL, 0, NULL, NULL);   
  char* chRtn = new char[nLen];
  WideCharToMultiByte(CP_ACP, 0, infoBuf, -1, chRtn, nLen, NULL, NULL);
 
  // create jstring
  jstring username = env->NewStringUTF(chRtn);
  return username;
}
 
JNIEXPORT jdouble JNICALL Java_com_gloomyfish_jnidemo_HelloJNI_calculateDistance
(JNIEnv *env, jobject obj, jdouble x, jdouble y) {
  double cx = x;
  double cy = y;
  double sum = pow(cx, 2) + pow(cy, 2);
  return sqrt(sum);
}


运行结果如下:

其中通过命令行实现JNI头文件生成,命令如下:

javah com.gloomyfish.jnidemo.HelloJNI

相关文章
|
9天前
|
前端开发 Java 关系型数据库
Java中的电子商务网站开发实战
Java中的电子商务网站开发实战
|
9天前
|
Java 数据挖掘 Linux
Java中的跨平台桌面应用开发实践
Java中的跨平台桌面应用开发实践
|
13天前
|
NoSQL Java Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
|
8天前
|
存储 Oracle Java
Java面试题:描述如何使用Eclipse或IntelliJ IDEA进行Java开发?
Java面试题:描述如何使用Eclipse或IntelliJ IDEA进行Java开发?
13 0
|
8天前
|
存储 安全 Java
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
15 0
|
7天前
|
设计模式 安全 编译器
【C++11】特殊类设计
【C++11】特殊类设计
26 10
|
12天前
|
C++
C++友元函数和友元类的使用
C++中的友元(friend)是一种机制,允许类或函数访问其他类的私有成员,以实现数据共享或特殊功能。友元分为两类:类友元和函数友元。类友元允许一个类访问另一个类的私有数据,而函数友元是非成员函数,可以直接访问类的私有成员。虽然提供了便利,但友元破坏了封装性,应谨慎使用。
41 9
|
7天前
|
存储 编译器 C语言
【C++基础 】类和对象(上)
【C++基础 】类和对象(上)
|
15天前
|
编译器 C++
【C++】string类的使用④(字符串操作String operations )
这篇博客探讨了C++ STL中`std::string`的几个关键操作,如`c_str()`和`data()`,它们分别返回指向字符串的const char*指针,前者保证以&#39;\0&#39;结尾,后者不保证。`get_allocator()`返回内存分配器,通常不直接使用。`copy()`函数用于将字符串部分复制到字符数组,不添加&#39;\0&#39;。`find()`和`rfind()`用于向前和向后搜索子串或字符。`npos`是string类中的一个常量,表示找不到匹配项时的返回值。博客通过实例展示了这些函数的用法。
|
15天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。