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型別轉換忘記了在哪找的,如果有人有連結,請發給我。
相關文章
- 程式的連結和裝入及Linux下動態連結的實現Linux
- golang可以呼叫C++的動態連結庫麼GolangC++
- c++實現單連結串列C++
- 動態連結庫和靜態連結庫的區別
- C#呼叫C++動態連結庫C#C++
- 資料結構——單連結串列的C++實現資料結構C++
- 帶頭結點的單連結串列實現(C++)C++
- 動態連結的步驟與實現
- 動態連結庫與靜態連結庫
- Java 簡單拼圖遊戲(實現音樂播放功能)Java遊戲
- C++:用棧實現反轉連結串列,超簡單!C++
- 關於cmake輸出動態連結庫名字的問題
- 簡單實現TCP下的大檔案高效傳輸TCP
- 一個簡單例子教會你C++動態庫的用法單例C++
- 實現一個簡單的C++協程庫C++
- Redis—簡單動態字串(SDS)Redis字串
- Java兩種方式實現連結串列的刪除,返回頭結點Java
- cmake 連結動態連結庫
- 單連結串列的插入刪除操作(c++實現)C++
- winform動態生成窗體並實現傳值返回ORM
- Win32動態連結庫與靜態連結庫的區別Win32
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 【資料結構】實現單連結串列(c++)資料結構C++
- 用 JavaScript 實現簡單拼圖遊戲JavaScript遊戲
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- redis string 簡單動態字串Redis字串
- C++的Stack模板的簡單實現C++
- 動態連結庫(DLL)
- 動態連結庫(轉)
- LRU Cache 的簡單 C++ 實現C++
- 動態繫結和靜態繫結的簡單理解
- java動態呼叫c++庫JavaC++
- 31:字串中最長的連續出現的字元字串字元
- 使用java動態位元組碼技術簡單實現arthas的trace功能。Java
- java實現簡單的JDBCJavaJDBC
- 簡單介紹python中的單向連結串列實現Python
- linux下靜態連結庫和動態連結庫的區別有哪些Linux
- C++ 手撕--基本資料結構的簡單實現C++資料結構