返回> 网站首页
vc++调用jar包
yoours2025-04-18 18:37:19
简介一边听听音乐,一边写写文章。
一、编写jar包
定义如下接口
static public String GetVersion()
public void SetLucenePath(String LucenePath)
// 添加索引
public void addIndex(Info info) throws IOException
// 关键字查询
public List<Info> search(String q, int pageSize, int pageIndex) throws Exception
// 删除索引索引
public void dellAllIndex() throws Exception
二、c++调用jar包
加载jvm必须使用loadlibrary方式,否则程序必须运行在jvm.dll同级目录下。
c++文本需要转换为utf8传输给java,接收的java文本需要转换成gb2312才能正常显示。
三、示例
bool CLuceneJava::Init()
{
JavaVMInitArgs vmArgs;
vmArgs.version = JNI_VERSION_1_8;
const int OPTION_COUNT = 3;
vmArgs.nOptions = OPTION_COUNT;
JavaVMOption options[OPTION_COUNT] = { 0 };
// classpath 指定为我们要调用的 jar 包路径
options[0].optionString = "-Djava.class.path=d://soskp.jar";
options[1].optionString = "-Xmx1024m"; // 最大堆大小
options[2].optionString = "-verbose:NONE"; //用于跟踪运行时的信息
vmArgs.options = options;
vmArgs.ignoreUnrecognized = JNI_TRUE;
HMODULE hModule = LoadLibrary("D:\\Java\\jdk-17.0.14\\bin\\server\\jvm.dll");
if (hModule == NULL)
return false;
typedef jint(JNICALL* CreateJavaVMFuncPtr)(JavaVM** pvm, void** penv, void* args);
CreateJavaVMFuncPtr CreateJavaVM = (CreateJavaVMFuncPtr)GetProcAddress(hModule, "JNI_CreateJavaVM");
JavaVM* jvm = nullptr;
JNIEnv* env = nullptr;
try {
jint res = (*CreateJavaVM)(&jvm, (void**)&env, &vmArgs);
if (res != JNI_OK)
return false;
}
catch (exception ex) {
printf("%s\r\n", ex.what());
}
// 找到 MyLucene
jclass class_MyLucene = env->FindClass("com/soskp/MyLucene/MyLucene");
jmethodID method_c = env->GetMethodID(class_MyLucene, "<init>", "()V");
jobject obj = env->NewObject(class_MyLucene, method_c);
// SetLucenePath
jmethodID method_SetLucenePath = env->GetMethodID(class_MyLucene, "SetLucenePath", "(Ljava/lang/String;)V");
jstring _jstrPath = env->NewStringUTF("d:\\luc");
env->CallVoidMethod(obj, method_SetLucenePath, _jstrPath);
env->DeleteLocalRef(_jstrPath);
/*
// dellAllIndex
jmethodID method_dellAllIndex = env->GetMethodID(class_MyLucene, "dellAllIndex", "()V");
env->CallVoidMethod(obj, method_dellAllIndex);
// 检查是否有异常
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
env->ExceptionClear();
}
*/
// GetVersion
jmethodID methodId_GetVersion = env->GetStaticMethodID(class_MyLucene, "GetVersion", "()Ljava/lang/String;");
jstring strVer = (jstring)env->CallStaticObjectMethod(class_MyLucene, methodId_GetVersion, "");
string str_Ver = jstring2string(env, strVer);
printf("%s\r\n", str_Ver.c_str());
// Info
jclass class_Info = env->FindClass("com/soskp/MyLucene/entity/Info");
jmethodID method_Infoc = env->GetMethodID(class_Info, "<init>", "()V");
jobject objInfo = env->NewObject(class_Info, method_Infoc);
// Info setId Integer
jint id = 11;
jclass intClass = env->FindClass("java/lang/Integer");
jmethodID intConstructor = env->GetMethodID(intClass, "<init>", "(I)V");
jobject intObj = env->NewObject(intClass, intConstructor, id);
// Info setId
jmethodID method_setId = env->GetMethodID(class_Info, "setInfoId", "(Ljava/lang/Integer;)V");
if(method_setId!=NULL)
printf("Info method_setId\n");
env->CallVoidMethod(objInfo, method_setId, intObj);
// Info setTitle
jmethodID method_setTitle = env->GetMethodID(class_Info, "setTitle", "(Ljava/lang/String;)V");
string tt1 = ConvertGB2312ToUTF8(t1);
jstring _jsetTitle = env->NewStringUTF(tt1.c_str());
env->CallVoidMethod(objInfo, method_setTitle, _jsetTitle);
env->DeleteLocalRef(_jsetTitle);
// Info setContent
jmethodID method_setContent = env->GetMethodID(class_Info, "setContent", "(Ljava/lang/String;)V");
string tt2 = ConvertGB2312ToUTF8(t2);
jstring _jsetContent = env->NewStringUTF(tt2.c_str());
env->CallVoidMethod(objInfo, method_setContent, _jsetContent);
env->DeleteLocalRef(_jsetContent);
// addIndex
jmethodID method_addIndex = env->GetMethodID(class_MyLucene, "addIndex", "(Lcom/soskp/MyLucene/entity/Info;)V");
env->CallVoidMethod(obj, method_addIndex, objInfo);
// 检查是否有异常
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
env->ExceptionClear();
}
printf("addIndex\n");
// search
jmethodID method_search = env->GetMethodID(class_MyLucene, "search", "(Ljava/lang/String;II)Ljava/util/List;");
string keyword = ConvertGB2312ToUTF8("驱动器");
jstring jQuery = env->NewStringUTF(keyword.c_str());
jobject objSearchResult = (jobject)env->CallObjectMethod(obj, method_search, jQuery, 20, 0);
env->DeleteLocalRef(jQuery);
// 检查是否有异常
if (env->ExceptionCheck())
{
env->ExceptionDescribe();
env->ExceptionClear();
}
printf("search\n");
//5. 遍历List并打印所有Info对象
if (objSearchResult == nullptr)
return 0;
jclass listClass = env->FindClass("java/util/List");
// 获取List的size方法
jmethodID listSizeMethod = env->GetMethodID(listClass, "size", "()I");
if (listSizeMethod == nullptr) {
return nullptr;
}
int size = env->CallIntMethod(objSearchResult, listSizeMethod);
printf("search result size: %d\n", size);
// 获取List的get方法
jmethodID listGetMethod = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
// 遍历每个元素
for (int i =0; i < size; i++)
{
jobject infoObj = env->CallObjectMethod(objSearchResult, listGetMethod, i);
// 获取Info类
jclass infoClass = env->FindClass("com/soskp/MyLucene/entity/Info");
// 获取Info的getTitle方法
jmethodID getTitleMethod = env->GetMethodID(infoClass, "getTitle", "()Ljava/lang/String;");
// 获取Info的getId方法
jmethodID getInfoIdMethod = env->GetMethodID(infoClass, "getInfoId", "()Ljava/lang/Integer;");
// 调用getTitle方法
jstring strTitle = (jstring)env->CallObjectMethod(infoObj, getTitleMethod);
const char* nameChars = env->GetStringUTFChars(strTitle, nullptr);
string cppName(nameChars);
env->ReleaseStringUTFChars(strTitle, nameChars);
// 调用getId方法
jobject objInfoId = env->CallObjectMethod(infoObj, getInfoIdMethod);
//5. 将返回的Integer对象转换为C++的int类型
jclass integerClass = env->FindClass("java/lang/Integer");
// 获取intValue方法的ID
jmethodID intValueMethod = env->GetMethodID(integerClass, "intValue", "()I");
// 调用intValue方法获取int值
jint id = env->CallIntMethod(objInfoId, intValueMethod);
// 打印Info对象的信息
cppName = ConvertUTF8toGB2312(cppName);
printf("Info: Name = %s, Id = %d\n",cppName.c_str(), id);
// 删除局部引用
env->DeleteLocalRef(infoObj);
env->DeleteLocalRef(strTitle);
}
// 删除局部引用
env->DeleteLocalRef(objSearchResult);
env->DeleteLocalRef(listClass);
printf("OK result\n");
// 检查是否发生了Java异常
jthrowable exception = env->ExceptionOccurred();
if (exception != NULL)
{
// 打印Java异常的堆栈跟踪信息
env->ExceptionDescribe();
// 抛出新的Java异常,类型为java.lang.RuntimeException,信息为"JNI error"
jclass runtimeExceptionClass = env->FindClass("java/lang/RuntimeException");
env->ThrowNew(runtimeExceptionClass, "JNI error");
}
jvm->DestroyJavaVM();
FreeLibrary(hModule);
return true;
}