【问题标题】:Build error when compiling java methods in C++ using jni.h使用 jni.h 在 C++ 中编译 java 方法时生成错误
【发布时间】:2015-04-22 18:33:25
【问题描述】:

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

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

我做了以下步骤。

第一步: 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;
    }
 }

第三步:编译java代码:

   javac Sample2.java

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

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

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

【问题讨论】:

    标签: java c++ compilation


    【解决方案1】:

    JNI_CreateJavaVMjni.h 中定义,所以我猜你的链接器没有找到jni.h。实际上,我将该文件和jni_md.h 与我的源代码一起放在我的项目目录中。

    注意jni.h 包含jni_md.h,因此在源代码中包含#include &lt;jni_md.h&gt; 是多余的。

    【讨论】:

    • 我在 C++ 解决方案文件夹中添加了标题。我仍然遇到同样的错误。
    • 嗯,错误是链接器错误,所以它没有找到它。我们不是读心术的人。如果不亲自检查您项目中的所有设置,我不知道您在哪里搞砸了。如果您将 jvm.lib 添加为依赖项,则链接器应该找到它。如果您可以尝试发布实际的编译和链接文本命令。
    • 肯定是链接错误。由于我使用的是 Visual Studio IDE,因此我不必编写任何命令来编译和链接。这就是我所做的。第 1 步:右键单击项目并选择属性并转到 Linker -> Input 并在 Additional Dependencies 中键入 jvm.lib 并在 Dealyed Loaded Dlls 中键入 jvm.dll 第 2 步:转到 Linker 下的 general 并给出路径附加库目录中的 jvm.lib 和 jvm.dll。 C:\Program Files\Java\jdk1.6.0_45\lib;C:\Program Files\Java\jre6\bin\server;%(AdditionalLibraryDirectories)
    • @TevaganthanVeluppillai Visual Studio 实际上使用命令行。 GUI 只是对您隐藏它。还有一个构建日志。在输出窗口中,它应该告诉你构建日志在哪里。
    • 谢谢泰勒。我找到了一种从以下链接获取构建日志的方法:msdn.microsoft.com/en-us/library/jj651643.aspx 因为我的构建日志是一个文本文件,我看不到在此处附加文本文件的方法。所以,我的构建日志在这里。dropbox.com/s/wrsoolkc52qmf51/OutputLog.txt?dl=0如果你有时间,请看一下,如果我错过了什么,请告诉我。
    【解决方案2】:

    所以,我解决了这个错误。以下是有效的 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;
     }
    

    【讨论】:

      猜你喜欢
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 2013-03-21
      • 1970-01-01
      相关资源
      最近更新 更多