Java連結c++動態庫實現字串的傳輸---簡單的字元拼裝返回
文章目錄
前言
之前發表了一篇Java連結c++動態庫簡單的加法計算
然後發現在這個基礎上做字串的傳遞和處理的過程中出現了亂碼,導致不得不尋找解決方案,我不停的思考、實踐,最終解決了。
這裡有點打臉,我還在之前的文章裡說用gcc命令生成.h檔案比較麻煩,但是這種方法非常好用,而且不需要再Java中匯入jna包,並且Java自帶的jni.h檔案有介面,在c++中比較好用。
下面是我解決的步驟希望對大家有所幫助。
提示:可能字串亂碼在Java那邊也能解決,但是我暫時沒有想到方法
一、Java中的操作
1、新建Java專案名為javaJni
2、新建一個class檔案新增以下內容
這裡第一個方法是做一個減法的介面,第二就是做一個字串的傳輸進行處理並返回字串,下面主函式呼叫生成的方法,不影響接下來生成.h檔案的操作。
package com.aijiao.test;
public class JNIDemo {
// 定義一個方法,該方法在C中實現
public native int testInt(int k);
public native String testString(String arr);
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary("TestJNI");
JNIDemo demo = new JNIDemo();
int k = demo.testInt(91);
System.out.println("value="+k);
String m = "msadasdasasd";
m = demo.testString(m);
System.out.println(m);
}
}
3、生成.h檔案
1)找到檔案的目錄,可以看到它的.class檔案
2)使用gcc命令生辰.h檔案
在專案bin層下輸入以下命令命令,生成.h檔案
javah -classpath . -jni com.aijiao.test.JNIDemo
生成的檔案如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_aijiao_test_JNIDemo */
#ifndef _Included_com_aijiao_test_JNIDemo
#define _Included_com_aijiao_test_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_aijiao_test_JNIDemo
* Method: testInt
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_aijiao_test_JNIDemo_testInt
(JNIEnv *, jobject, jint);
/*
* Class: com_aijiao_test_JNIDemo
* Method: testString
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_aijiao_test_JNIDemo_testString
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
二、在c++中的操作
1.建立動態連結庫專案–名字為TestJNI
2.在原始檔右擊建立類–檔名字為TestJNI
3.把生成的.h檔案和jni.h、Jni_md.h移到動態庫的目錄下,如圖
4.標頭檔案右擊匯入現有項,把三個.h檔案新增到專案
5.在生成的TestJNI.cpp檔案中新增以下內容
#include "pch.h"
#include "com_aijiao_test_JNIDemo.h"
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
JNIEXPORT jint JNICALL Java_com_aijiao_test_JNIDemo_testInt
(JNIEnv *, jobject, jint a) {
int value = a - 7;
return value;
}
JNIEXPORT jstring JNICALL Java_com_aijiao_test_JNIDemo_testString
(JNIEnv * env, jobject obj, jstring a) {
char* b = jstringTochar(env, a);
string c = b;
c = c + c;
//(env)->NewStringUTF(a)
return (env)->NewStringUTF(c.c_str());
}
char* jstringTochar(JNIEnv *env, jstring jstr)
{ //UTF8/16轉換成gb2312
int length = (env)->GetStringLength(jstr);
const jchar* jcstr = (env)->GetStringChars(jstr, 0);
int clen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, NULL, 0, NULL, NULL);
char* rtn = (char*)malloc(clen); //更正。作者原來用的是(char*)malloc( length*2+1 ),當java字串中同時包含漢字和英文字母時,所需緩衝區大小並不是2倍關係。
int size = 0;
size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, clen, NULL, NULL);
if (size <= 0)
return NULL;
(env)->ReleaseStringChars(jstr, jcstr);
rtn[size] = 0;
return rtn;
}
6.修改生成的.h檔案
java生成.h檔案中的#include <jni.h>改為#include “jni.h”,並且把char* jstringTochar(JNIEnv *env, jstring jstr);新增到生成的.h檔案中
7.生成解決方案
三、執行Java呼叫c的方法
執行JNIDemo,發現執行成功,並且字串沒有亂碼
總結
以上就是我的整個過程,其中在c++中有一個jstringTochar類,是把Java傳來的string型別的字串轉為char*,然後轉為string型別進行操作,因為java和c++的編碼形式不同,這個介面就是把Java中的編碼型別UTF8/16轉換成c++的gb2312編碼形式。
下期預告
我下面會更新在linux中java如何呼叫so庫
發文不易,請點贊支援支援
參考文獻
JNI入門教程
jstringTochar型別轉換忘記了在哪找的,如果有人有連結,請發給我。
相關文章
- C#呼叫C++動態連結庫C#C++
- 資料結構——單連結串列的C++實現資料結構C++
- 動態連結庫與靜態連結庫
- 動態連結的步驟與實現
- C++:用棧實現反轉連結串列,超簡單!C++
- Java兩種方式實現連結串列的刪除,返回頭結點Java
- redis string 簡單動態字串Redis字串
- Redis—簡單動態字串(SDS)Redis字串
- cmake 連結動態連結庫
- 一個簡單例子教會你C++動態庫的用法單例C++
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 簡單介紹python中的單向連結串列實現Python
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- winform動態生成窗體並實現傳值返回ORM
- linux下靜態連結庫和動態連結庫的區別有哪些Linux
- java動態呼叫c++庫JavaC++
- 如何用C/C++實現去除字串頭和尾指定的字元C++字串字元
- C++ 手撕--基本資料結構的簡單實現C++資料結構
- java實現簡單的JDBCJavaJDBC
- 使用java動態位元組碼技術簡單實現arthas的trace功能。Java
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- 動態連結庫的生成和使用(二)
- 動態連結庫(DLL)的建立和使用
- ncurses輸出函式:字元+字串的輸出函式字元字串
- ncurses輸入函式:字元+字串的輸入函式字元字串
- 簡單動態字串(simple dynamic string)SDS字串
- 深入理解Redis 資料結構—簡單動態字串sdsRedis資料結構字串
- Java------簡單的輸入/輸出Java
- Linux環境下:程式的連結, 裝載和庫[靜態連結]Linux
- java實現棧的簡單操作Java
- 反轉連結串列(C++簡單區)C++
- 計算返回單、雙位元組字元混合字串長度字元字串
- JavaScript字串物件 之 根據字元返回位置、根據位置返回字元、字串操作方法JavaScript字串物件字元
- 簡單的單向連結串列
- 封裝動態庫dll與靜態庫lib(原理及簡單例項)封裝單例
- 輸出字串中出現次數最多的字元和次數字串字元
- Redis系列(一)底層資料結構之簡單動態字串Redis資料結構字串
- java 動態代理簡單使用Java