java调用C++ dll
使用IDEA新建一个名为Java2cpp的Java工程,并且使用模板。
用native关键字包裹需要用到的C++中的函数
package com.log.jni;
public class Java2cpp {
public native void LOG_LOAD_CONFIG(String address);
public native void LOG_DEV_INFO_2(String name,int uid,String des);
public native void LOG_DEV_WARNING_2(String name,int uid,String des);
public native void LOG_DEV_ERROR_2(String name,int uid,String des);
public native void display();
public static void main(String[] args){
String log="D:\\UIH\\appdata\\MicroCT\\Console\\LogConfig\\TestLog.xml";
Java2cpp test=new Java2cpp();
test.LOG_LOAD_CONFIG(log);
test.LOG_DEV_INFO_2("TestLog.xml",0x9999,"ysl");
test.LOG_DEV_WARNING_2("TestLog.xml",0x9999,"rose");
test.LOG_DEV_ERROR_2("TestLog.xml",0x9999,"jack");
test.display();
}
}
运行:javac Java2cpp.java --生成.class文件
javac -h ./ Java2cpp.java --生成.h文件
使用vs新建一个静态库项目,名为DllLog
将Java工程中生成的.h文件复制到DllLog文件下
找到Java安装路径下的include文件复制jni.h include下win32中的jawt_md.h jni_md.h,将这三个文件都复制到DllLog中
在源文件下添加一个.cpp文件DllLog.cpp引入相关的头文件
#include "pch.h"
#include "com_log_jni_Java2cpp.h"
#include "InfrasUtils/McsfLogger/mcsf_logger.h"
完成相应的函数
char* jstringToChar(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
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;
}
//jstring to string
std::string jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
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);
std::string stemp(rtn);
free(rtn);
return stemp;
}
JNIEXPORT void JNICALL Java_com_log_jni_Java2cpp_display
(JNIEnv* env, jobject obj){
puts("*** Hello JNI *******");
}
JNIEXPORT void JNICALL Java_com_log_jni_Java2cpp_LOG_1LOAD_1CONFIG
(JNIEnv* env , jobject obj , jstring jstr) {
//jstring to string
string str=jstringTostring(env, jstr);
LOG_LOAD_CONFIG(str);
}
JNIEXPORT void JNICALL Java_com_log_jni_Java2cpp_LOG_1DEV_1INFO_12
(JNIEnv* env, jobject obj, jstring jname, jint uid, jstring jdes) {
jboolean isCopy;
char* chardata = jstringToChar(env, jname);
char* chardes = jstringToChar(env, jdes);
std::string name = chardata;
std::string des = chardes;
LOG_LOAD_CONFIG("D:\\UIH\\appdata\\MicroCT\\Console\\LogConfig\\MicroConsoleStartUpLog1.xml");
LOG_DEV_INFO_2(name,uid)<<des;
}
JNIEXPORT void JNICALL Java_com_log_jni_Java2cpp_LOG_1DEV_1WARNING_12
(JNIEnv* env, jobject obj, jstring jname,jint uid, jstring jdes) {
char* chardata = jstringToChar(env, jname);
char* chardes = jstringToChar(env, jdes);
std::string name = chardata;
std::string des = chardes;
LOG_LOAD_CONFIG("D:\\UIH\\appdata\\MicroCT\\Console\\LogConfig\\MicroConsoleStartUpLog1.xml");
LOG_DEV_WARNING_2(name, uid)<< des;
}
JNIEXPORT void JNICALL Java_com_log_jni_Java2cpp_LOG_1DEV_1ERROR_12
(JNIEnv* env , jobject obj, jstring jname, jint uid, jstring jdes) {
char* chardata = jstringToChar(env, jname);
char* chardes = jstringToChar(env, jdes);
std::string name = chardata;
std::string des = chardes;
LOG_LOAD_CONFIG("D:\\UIH\\appdata\\MicroCT\\Console\\LogConfig\\MicroConsoleStartUpLog1.xml");
LOG_DEV_ERROR_2(name, uid)<< des;
}
在项目文件处右键选择属性—VC++目录 --常规 --包含目录下添加目录
添加当前文件夹…/DllLog java的安装路径下的include目录
生成解决方案,将生成的DllLog.dll复制到Java2cpp\src\com\ypoj\jni文件下
运行 java Java2cpp.java
调用成功