gpt4 book ai didi

java - 在 C++ 中从 JNI 调用 Java Jar 代码

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:03:32 25 4
gpt4 key购买 nike

我试图在我的 C++ 语言中模拟这个 (http://snuggletex.sourceforge.net/maven/xref/uk/ac/ed/ph/snuggletex/samples/MinimalExample.html) 代码,以便在本地获得一些 LaTeX 到 MathML 的数学公式转换,但是在最后一次方法调用之后,我的执行被中止

#include <iostream>
#include <string.h>
#include <jni.h>

using namespace std;

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH "snuggletex-1.2.2/snuggletex-core-1.2.2.jar" /* where Prog.class is */

#define SNUGGLE_ENGINE "uk/ac/ed/ph/snuggletex/SnuggleEngine"
#define SNUGGLE_INPUT "uk/ac/ed/ph/snuggletex/SnuggleInput"
#define SNUGGLE_SESSION "uk/ac/ed/ph/snuggletex/SnuggleSession"
#define STRING "java/lang/String"

JNIEnv *env;
JavaVM *jvm;
jint res;

void initJVM() {

#ifdef JNI_VERSION_1_2
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString =
"-Djava.class.path=" USER_CLASSPATH;
vm_args.version = 0x00010002;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
#else
JDK1_1InitArgs vm_args;
char classpath[1024];
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the default system class path */
sprintf(classpath, "%s%c%s",
vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
#endif /* JNI_VERSION_1_2 */


}

void closeJVM() {
jvm->DestroyJavaVM();
}


jstring JNU_NewStringNative(const char *str)
{
jstring result;
jbyteArray bytes = 0;
jclass Cstr;
int len;

len = strlen(str);
bytes = (env)->NewByteArray( len);
Cstr = (env)->FindClass(STRING);
if (bytes != NULL) {
jmethodID mid;
(env)->SetByteArrayRegion(bytes, 0, len,(jbyte *)str);
mid = env->GetStaticMethodID(Cstr, "<init>", "([B)V");
result = (jstring) (env)->NewObject(Cstr,mid,bytes);
(env)->DeleteLocalRef(bytes);
return result;
} /* else fall through */
return NULL;
}

int parse_latex(char* input) {

jclass engine, Cinput, Csession;
jmethodID mid;
jstring jstr;
jclass stringClass;
jobjectArray args;
jstring latex = JNU_NewStringNative(input);
jstring result;



engine = env->FindClass(SNUGGLE_ENGINE);
Cinput = env->FindClass(SNUGGLE_INPUT);
Csession = env->FindClass(SNUGGLE_SESSION);

if (engine==NULL) return -1;
mid = env->GetStaticMethodID(engine, "<init>", "()V");
jobject snuggle = env->NewObject(engine, mid);

mid = env->GetStaticMethodID(engine, "createSession", "()V");
jobject session = env->NewObject(engine, mid);


//if (cls==NULL) return -1;
mid = env->GetStaticMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
jobject input_elem = env->NewObject(Cinput, mid,latex);

mid = env->GetStaticMethodID(Csession , "parseInput", "(Luk/ac/ed/ph/snuggletex/SnuggleInput;)V");
env->CallNonvirtualVoidMethod(session, Csession, mid, input_elem);

printf("obtaining method\n");
mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
printf("calling method\n");
try {
result = (jstring)env->CallObjectMethod(session, mid);
printf("ok\n");
} catch (...) {
jthrowable exc;
exc = (env)->ExceptionOccurred();
if (exc) {
env->ExceptionDescribe();
//Returns java.lang.NullPointerException
}
}




return 0;
}



int main() {

int resint;
initJVM();

resint = parse_latex("$$5^2$$");

closeJVM();
return resint;

}

我正在编译:

 g++ -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -L/usr/lib/jvm/java-1.5.0-gcj-4.4/jre/lib/amd64/ -L/usr/lib/jvm/java-1.5.0-gcj-4.4/jre/lib/amd64/client -ljvm -Wl,-rpath,/usr/lib/jvm/java-1.5.0-gcj-4.4/jre/lib/amd64/client -lstdc++ runner.cpp

我哪里错了?提前致谢

编辑

据我所知,env->CallObjectMethod(session, mid);//Aborted 抛出了一个C++异常,尤其是 java.lang.NullPointerException

解决方案

#include <iostream>
#include <string.h>
#include <jni.h>
#include <stdlib.h>

using namespace std;

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH "snuggletex-1.2.2/snuggletex-core-1.2.2.jar" /* where Prog.class is */

#define SNUGGLE_ENGINE "uk/ac/ed/ph/snuggletex/SnuggleEngine"
#define SNUGGLE_INPUT "uk/ac/ed/ph/snuggletex/SnuggleInput"
#define SNUGGLE_SESSION "uk/ac/ed/ph/snuggletex/SnuggleSession"
#define STRING "java/lang/String"

JNIEnv *env;
JavaVM *jvm;
jint res;

void initJVM() {

#ifdef JNI_VERSION_1_2
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString =
"-Djava.class.path=" USER_CLASSPATH;
vm_args.version = 0x00010002;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
#else
JDK1_1InitArgs vm_args;
char classpath[1024];
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the default system class path */
sprintf(classpath, "%s%c%s",
vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
#endif /* JNI_VERSION_1_2 */


}

void closeJVM() {
jvm->DestroyJavaVM();
}


jstring JNU_NewStringNative(const char *str)
{
jclass strClass = env->FindClass("java/lang/String");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jstring encoding = env->NewStringUTF("GBK");

jbyteArray bytes = env->NewByteArray(strlen(str));
env->SetByteArrayRegion(bytes, 0, strlen(str), (jbyte*)str);
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}


const char * parse_latex(char* input) {

jclass engine, Cinput, Csession;
jmethodID mid;
jstring jstr;
jclass stringClass;
jobjectArray args;
jstring latex = JNU_NewStringNative(input);
jstring result;



engine = env->FindClass(SNUGGLE_ENGINE);
Cinput = env->FindClass(SNUGGLE_INPUT);
Csession = env->FindClass(SNUGGLE_SESSION);

// SnuggleEngine engine = new SnuggleEngine();
mid = env->GetMethodID(engine, "<init>", "()V");
jobject snuggle = env->NewObject(engine, mid);

// SnuggleSession session = engine.createSession();
mid = env->GetMethodID(engine, "createSession", "()L"SNUGGLE_SESSION";");
jobject session = env->CallObjectMethod(snuggle, mid);

// SnuggleInput input = new SnuggleInput("$$ x+2=3 $$");
mid = env->GetMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
jobject input_elem = env->NewObject(Cinput, mid, latex);

// session.parseInput(input);
mid = env->GetMethodID(Csession , "parseInput", "(L"SNUGGLE_INPUT";)Z");
env->CallBooleanMethod(session, mid, input_elem);

// String xmlString = session.buildXMLString();
mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
result = (jstring) env->CallObjectMethod(session, mid);

printf("here\n");
const jbyte *str = (jbyte *)(env)->GetStringUTFChars(result, NULL);

return ((char*)str);


return 0;
}



int main() {

const char* resint;
initJVM();

resint = parse_latex("$$ x+2=3 $$");
if (resint) printf("%s\n", resint); else printf("error\n");

closeJVM();
return (resint!=0);

}

最佳答案

你调用了错误的方法。

// SnuggleEngine engine = new SnuggleEngine();
mid = env->GetMethodID(engine, "<init>", "()V");
jobject snuggle = env->NewObject(engine, mid);

// SnuggleSession session = engine.createSession();
mid = env->GetMethodID(engine, "createSession", "()L"SNUGGLE_SESSION";");
jobject session = env->CallObjectMethod(snuggle, mid);

// SnuggleInput input = new SnuggleInput("$$ x+2=3 $$");
mid = env->GetMethodID(Cinput , "<init>", "(Ljava/lang/String;)V");
jobject input_elem = env->NewObject(Cinput, mid, latex);

// session.parseInput(input);
mid = env->GetMethodID(Csession , "parseInput", "(L"SNUGGLE_INPUT";)Z");
env->CallBooleanMethod(session, mid, input_elem);

// String xmlString = session.buildXMLString();
mid = env->GetMethodID(Csession , "buildXMLString", "()Ljava/lang/String;");
result = (jstring) env->CallObjectMethod(session, mid);

我没有测试它。希望它有效!

关于java - 在 C++ 中从 JNI 调用 Java Jar 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16750317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com