jni c调用java jar,在C ++中从JNI调用Java Jar代码

I'm trying to emulate this (http://snuggletex.sourceforge.net/maven/xref/uk/ac/ed/ph/snuggletex/samples/MinimalExample.html) code inside my C++ language, in order to obtain natively some LaTeX to MathML conversion of mathematical formulæ, but after the last method invocation, my execution gets aborted

#include

#include

#include

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, "", "([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, "", "()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 , "", "(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;

}

I'm compiling with:

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

Where am I wrong? Thanks in advance

EDIT

As far as I can see, env->CallObjectMethod(session, mid);//Aborted throws a C++ exception,

and particularly a java.lang.NullPointerException

SOLUTION

#include

#include

#include

#include

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, "", "([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, "", "()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 , "", "(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);

}

解决方案

You're invoking the wrong method.

// SnuggleEngine engine = new SnuggleEngine();

mid = env->GetMethodID(engine, "", "()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 , "", "(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);

I didn't test it. Hope it works!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值