JAVA调用C++
步骤:
1)编写java文件(Test.java)
2)生成.h头文件(javah -jni Test)
3)用cpp实现这个头文件(Test.cpp)
Test.java
public class Test { public native static String callC(String str); public static void main(String[] args){ System.loadLibrary("JavaCallCpp"); String str = callC("java_string"); System.out.println("[java]: " + str); } }
Test.h
#include <jni.h> #ifndef _Included_Test #define _Included_Test #ifdef __cplusplus extern "C" { #endif JNIEXPORT jstring JNICALL Java_Test_callC (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
Test.cpp
#include "Test.h" JNIEXPORT jstring JNICALL Java_Test_callC(JNIEnv* env, jclass jc, jstring str) { printf("[C++]: %s\n", jstringToString(env, str)); char* cppStr = "c++_string"; printf("[C++]: %s\n", cppStr); return stringToJstring(env, cppStr); } //jstring to char* char* jstringToString(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } //char* to jstring jstring stringToJstring(JNIEnv* env, const char* str) { jstring encoding = env->NewStringUTF("gbk"); jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(str)); env->SetByteArrayRegion(bytes, 0, strlen(str), (jbyte*)str); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); }