使用jni.h在C ++中编译java方法时构建错误

时间:2015-04-22 18:33:25

标签: java c++ compilation

我试图在Visual Studio C ++环境中从Java类运行一些方法。我收到了与CreateJavaVM相关的错误。

请您帮我找到解决方案吗?

我做了以下步骤。

步骤1: JDK 1.6安装在以下路径下:C:\ Program Files \ Java 有以下2个子目录:jdk1.6.0_45,jre6

第2步:编写一个简单的java程序。

public class Sample2
{
   public static int intMethod(int n)
   {
     return n*n;
   }
   public static boolean booleanMethod(boolean bool) 
   {
    return !bool;
    }
 }

第3步:编译java代码:

   javac Sample2.java

第4步:创建Visual Studio C ++程序。 Visual C ++ CLR控制台应用程序。

第5步:添加其他依赖项。 (jvm.lib和jvm.dll) a)选择项目 - >属性 - >链接器 - >输入 - >附加依赖项:jvm.lib b)选择项目 - >属性 - >链接器 - >输入 - >延迟加载Dll:jvm.dll

第6步:添加包含目录 a)选择项目 - >属性 - >配置属性 - > C / C ++ - >一般 - >其他包含目录:C:\ Program Files \ Java \ jdk1.6.0_45 \ lib; C:\ Program Files \ Java \ jdk1.6.0_45 \ include \ win32; C:\ Program Files \ Java \ jdk1.6.0_45 \ include

第7步:编写C ++代码以运行java方法。

  #include "stdafx.h"
  #include "jni.h"
  #include <jni_md.h>
  using namespace System;

  int main(array<System::String ^> ^args)
  {

    JavaVM *jvm;   /* denotes a Java VM */
    JNIEnv *env;  /* pointer to native method interface */
    jint square;
    jboolean not;

    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */

    JavaVMOption *options = new JavaVMOption[1];

    options[0].optionString = "-Djava.class.path=C:\\JavaCode";  

   vm_args.version = JNI_VERSION_1_6;
   vm_args.options = options;
   vm_args.nOptions = 1;
   vm_args.ignoreUnrecognized = false;

   int res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);

   jclass cls = env->FindClass("Sample2");

   jmethodID mid = env->GetStaticMethodID(cls, "staticInt", "(I)I");

   env->CallStaticVoidMethod(cls, mid,10);

   if(cls !=0)
   {   
     mid = env->GetStaticMethodID(cls,"intMethod","(I)I");    

   if(mid !=0)
   {  
    square = env->CallStaticIntMethod(cls, mid, 5);       
    printf("Result of intMethod: %d\n", square);
   }

   mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z");

    if(mid !=0)
    { 
     not = env->CallStaticBooleanMethod(cls, mid, 1);
     printf("Result of booleanMethod: %d\n", not);
    }
 }

 jvm->DestroyJavaVM();

 Console::Read();
 return 0;
}

第8步:当我构建项目时,我收到以下错误:

1>------ Build started: Project: 1, Configuration: Debug Win32 ------

1>LINK : warning LNK4199: /DELAYLOAD:jvm.dll ignored; no imports found from jvm.dll

1>1.obj : warning LNK4248: unresolved typeref token (0100000F) for '_jmethodID'; image may not run

1>1.obj : error LNK2028: unresolved token (0A000016) "extern "C" long __stdcall JNI_CreateJavaVM(struct JavaVM_ * *,void * *,void *)" (?JNI_CreateJavaVM@@$$J212YGJPAPAUJavaVM_@@PAPAXPAX@Z) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)

1>1.obj : error LNK2019: unresolved external symbol "extern "C" long __stdcall JNI_CreateJavaVM(struct JavaVM_ * *,void * *,void *)" (?JNI_CreateJavaVM@@$$J212YGJPAPAUJavaVM_@@PAPAXPAX@Z) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)

1>C:\Users\tveluppillai\Desktop\Test1\1\Debug\1.exe : fatal error LNK1120: 2 unresolved externals

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

有人会帮我解决这个错误吗?

2 个答案:

答案 0 :(得分:0)

JNI_CreateJavaVMjni.h中定义,所以我的猜测是你的链接器找不到jni.h。我实际上将该文件和jni_md.h放在我的项目目录中,并附上我的源代码。

请注意,jni.h包含jni_md.h,因此源代码中包含#include <jni_md.h>是多余的。

答案 1 :(得分:0)

所以,我解决了错误。以下是工作的C ++代码。

// 1.cpp : main project file.

  #include "stdafx.h"
  #include "jni.h"
  #include <windows.h>
  using namespace System;


  int CallJava()
  {

   JavaVM *jvm;   /* denotes a Java VM */

   JNIEnv *env;  /* pointer to native method interface */

   jint square;

   jboolean not;

   JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */

   JavaVMOption *options = new JavaVMOption[1];

   options[0].optionString = "-Djava.class.path=C:\\JavaCode";  

   vm_args.version = JNI_VERSION_1_6;
   vm_args.options = options;
   vm_args.nOptions = 1;
   vm_args.ignoreUnrecognized = false;

   HINSTANCE hinstLib;  

    hinstLib = LoadLibrary(TEXT("C:\\Program Files\\Java\\jdk1.6.0_45\\jre\\bin\\server\\jvm.dll"));

  if(hinstLib==0)
  {
   printf("Error");
  }

  if(hinstLib!= NULL)
  {
  typedef jint (JNICALL *PtrCreateJavaVM)(JavaVM **, void **, void *);

    PtrCreateJavaVM ptrCreateJavaVM =  (PtrCreateJavaVM)GetProcAddress(hinstLib,"JNI_CreateJavaVM");

   int res = ptrCreateJavaVM(&jvm, (void**)&env, &vm_args);

   jclass cls = env->FindClass("Sample2");

   jmethodID mid;   

   if(cls !=0)
   {   
    mid = env->GetStaticMethodID(cls,"intMethod","(I)I");
    if(mid !=0)
    {  
      square = env->CallStaticIntMethod(cls, mid, 5);       
      printf("Result of intMethod: %d\n", square);
    }

   mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z");
   if(mid !=0)
   { 
     not = env->CallStaticBooleanMethod(cls, mid, 1);
     printf("Result of booleanMethod: %d\n", not);
    }
  }
   jvm->DestroyJavaVM();
 }
else
{
  printf("Library is NULL");
}
   Console::Read();
   return 0;
}

 int main(array<System::String ^> ^args)
 {
 CallJava();
 Console::Read();
 return 0;
 }