Как избежать ошибки UnsatisfiedLinkError при вызове C ++ из java из приложения C ++?

Я встраиваю Java в приложение C ++. В рамках этого мне нужно предоставить собственные функции для java, а также вызвать java-функции из C ++.

Нужно ли мне помещать функции, которые я хочу вызывать из java, в общую библиотеку? Или их можно каким-то образом скомпилировать в хост-приложение?

Вот то, что я пробовал до сих пор, но он дает java.lang.UnsatisfiedLinkError

Компиляция

Я создаю OS X 10.5, используя

g++ -Wall -I/System/Library/Frameworks/JavaVM.framework/Headers/ -framework JavaVM -g test.cpp

] Тестовый файл Java: TestObject.java

// To build this you need to do a `javac TestObject.java`
// To get the signatures do a `javap -d TestObject`
// To generate the .h file do a `javah TestObject`
public class TestObject
{
    public native TestObject get_property( String k ); 
}

Тестовый файл C ++: test.cpp

#include <jni.h>
#include <assert.h>


JNIEXPORT jobject JNICALL Java_TestObject_get_1property(JNIEnv * jni_env, jobject obj, jstring key)
{
  //Just a stub implementation for now.
  jclass klass = jni_env->GetObjectClass( obj );
  jmethodID constructor = jni_env->GetMethodID( klass, "<init>", "()V");
  jobject retval = jni_env->NewObject(klass, constructor );

  return retval;
}




int main()
{
  JavaVM* jvm;
  JavaVMInitArgs vm_args;
  JavaVMOption options[1];

  vm_args.version = JNI_VERSION_1_4;
  vm_args.nOptions = 1;
  options[0].optionString = "-Djava.class.path=.";
  vm_args.options = options;
  vm_args.ignoreUnrecognized = JNI_FALSE;

  JNIEnv * env;
  JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);

  jclass klass = (env)->FindClass("TestObject");
  assert( klass );

  jmethodID constructor = env->GetMethodID( klass, "<init>", "()V");
  assert( constructor );

  jobject obj = env->NewObject(klass, constructor );

  jmethodID test_method = (env)->GetMethodID( klass, "get_property", "(Ljava/lang/String;)LTestObject;" );
  assert( test_method );

  jvalue args[1];
  args[0].l = env->NewStringUTF("k");

  jobject rv = env->CallObjectMethodA(obj, test_method, args );

  jthrowable exc = env->ExceptionOccurred();
  if(exc)
  {
    env->ExceptionDescribe();
    env->ExceptionClear();
  }

  //TODO: do something with rv

}

6
задан Michael Anderson 1 August 2011 в 02:03
поделиться