Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 489|回复: 0

C++调用Java方法时jvm.dll相关错误 【每次记录完后都被瞬间解决了……】

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-10 12:50:55 | 显示全部楼层 |阅读模式

    在编程的学习过程中,愈发感觉到了女性思维在这方面的局限性。

    背景介绍:

      为了学习JNI中C++对Java的调用,在阅读《JNI技术手册》的同时加以练习。但根据示例代码编写过程中总出现各种

    奇怪的问题(一度后悔自己装了win7 64位系统,而电脑之前是预装win8 32位的...)。由于Java部分的代码非常简单,

    没有出现任何错误,javac、javah命令也能正常输出.class文件和头文件。但C++部分却报错了。所学习的示例代码意图

    通过C++调用Java,生成一个.exe的启动文件。

      Java代码如下:    

     1 public class C2Java {
     2     
     3     public C2Java(){
     4         super();
     5     }
     6     
     7     public static int add(int a,int b){
     8         return a+b;
     9     }
    10     
    11     public boolean judge(boolean bool){
    12         return !bool;
    13     }    
    14 }

      C++代码如下: 

    // c2java.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include "windows.h"
    
    using namespace std; 
    
    int main(int argc, char* argv[])
    {
        JavaVMOption options[1]; 
        JNIEnv *env; 
        JavaVM *jvm; 
        JavaVMInitArgs vm_args; 
        long status; 
        jclass cls; 
        jmethodID mid; 
        jint square; 
        jboolean not; 
        jobject jobj;    
        options[0].optionString = "-Djava.class.path=.";   
    
        vm_args.version = JNI_VERSION_1_6; 
        vm_args.nOptions = 1; 
        vm_args.options = options;
        vm_args.ignoreUnrecognized = JNI_TRUE;   
    
        status = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
    
         if(status != JNI_ERR) { 
            cls = env->FindClass("C2Java"); 
            if(cls !=0) { 
                mid = env->GetStaticMethodID(cls, "add", "(II)I"); 
                if(mid !=0) { 
                    square = env->CallStaticIntMethod(cls, mid, 5, 5); 
                    std::cout << square << std::endl; 
                } 
                mid = env->GetMethodID(cls, "<init>", "()V"); 
                if(mid !=0) { 
                    jobj=env->NewObject(cls, mid); 
                    std::cout << "init ok"<< std::endl; 
                } 
                mid = env->GetMethodID(cls, "judge", "(Z)Z"); 
                if(mid !=0) { 
                    not= env->CallBooleanMethod(jobj, mid, 1); 
                    if(!not) { 
                        std::cout << "Boolean ok"<< std::endl; 
                    } 
                } 
            } 
            jvm->DestroyJavaVM();  
            return 0; 
        } else
            return -1; 
    }

      由于创建jvm过程中可以通过两种方式加载jvm.dll动态链接库文件,在两种方式的尝试中发现了截然不同的错误。

      错误内容:

      错误1:使用如上代码,通过在path中添加jvm.dll路径、在工程/属性/链接器/输出中添加jvm.lib依赖库,实现dll文件的静态加载。反复测试了很多次,

    始终报错如下:

      单步调试似乎也不能使用,查阅相关资料,将console改为window报的错更多…… 之后又仔细搜寻相关教程,根据:http://andy-li-chn.iteye.com/blog/1175075

    的说法:“自定义的类JVM无法找到,例子只说让自己编写自定义的类,但并没有说生成的类应该放在什么地方才可以被JVM正确的找到。通常根据需要我们的类是放在特定

    的目录下的,而且放在jvm路径下也是不安全的,所以在网上的大多数例子都缺少一步,设置自定义类的路径 "。根据这个思路,决定自定义类路径并动态加载dll文件。

     错误2: 将自己的C++代码相关部分修改为:

      //定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数   
        typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);   
      const  char  szJvmPath[] = "C:\\Program Files\\Java\\jdk1.7.0_51\\jre\\bin\\server\\jvm.dll";
        HINSTANCE hInstance = ::LoadLibrary(szJvmPath); 
        
        if (hInstance == NULL)   
        {   
            cout<< "LoadLibrary False"<<endl;
            cout<<::GetLastError()<<endl;
            return -2;   
        }   
        //取得里面的JNI_CreateJavaVM函数指针   
        PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");   
        status = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args); 

      运行后返回值为-2,GetLastError的内容为193,意思是动态加载dll文件失败了。设置断点查看各变量内容时,发现LoadLibrary的返回值为空。查阅资料后

    进行修改仍不能正常运行。目前还未找到方法来成功解决此问题T.T

    运行。

      快拯救我吖神奇的博客园... 只希望每次愚蠢的错误都能深深印刻在我的脑海里……

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 05:52 , Processed in 0.061183 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表