简体   繁体   English

如何让任何用户运行从其C ++代码读取Java方法的.exe程序?

[英]How to let any users run .exe program that reads java methods from its c++ code?

Here the zip file of source code: http://cfile218.uf.daum.net/attach/254F2D4F5211EF93107910 这里是源代码的zip文件: http : //cfile218.uf.daum.net/attach/254F2D4F5211EF93107910

,or visible source code in the bottom. 或底部可见的源代码。

I just compiled and ran it on my PC: worked fine in both debug and release mode. 我只是在PC上编译并运行它:在调试和发布模式下都可以正常工作。

However, if I try to run it on another PC (Windows XP is installed in), it shows an error saying that I do not have "jvm.dll" so it cannot run it. 但是,如果我尝试在另一台PC(已安装Windows XP)上运行它,则会显示一条错误消息,提示我没有“ jvm.dll”,因此它无法运行。

Therefore I installed java from the address " http://java.com/en/download/index.jsp " and runned it. 因此,我从地址“ http://java.com/en/download/index.jsp ”安装了Java并运行了它。 However, it still said same error. 但是,它仍然说同样的错误。

It is my problem.... 这是我的问题。

How would I make it be run on other normal PCs that has no JDK or MSVC? 如何使它在没有JDK或MSVC的其他普通PC上运行? because normal users definitely do not own JDK.. 因为普通用户绝对不拥有JDK。

## ================================ ##
// it is the c++ code that starts JVM and run java source code...

               #include <iostream>
              #include <windows.h>
             #include <jni.h>

       #pragma comment(lib, "jvm.lib")

       using namespace std;


       void main(){

    cout<<"JVM Create Start!!"<<endl;

    // JavaVM create & JVM environment setting start
    JavaVMOption options[1];
    JavaVMInitArgs vm_args;
    JNIEnv *env;
    JavaVM *jvm;
    long status;

    options[0].optionString = "-Djava.class.path=.";
    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    // JavaVM create & JVM environment setting end

    cout<<"JVM Operating......."<<endl;

    cout<<"\n10+20?\n"<<endl;

    jclass cls;
    jmethodID mid;
    jobject obj;
    int staticresult=0;
    int result=0;

    if(status != JNI_ERR)
    {
        cls = env->FindClass("FirstJavaEx");

        if(cls != 0)
        {
            //
            // Use the static method start
            //
            cout<<"\t'static'start calling method" << endl;
            mid = env->GetStaticMethodID(cls, "staticAdd", "(II)I");
            if (mid != 0)
            {
                staticresult = env->CallStaticIntMethod(cls, mid, 10, 20);
                cout<<"\t'static'result: " << staticresult << endl;
            }
            else
            {
                printf("mid error\n");
                return;
            }
            //
            // Use the static method end
            //

            //
            //Create the Instance of InvokeFirstEX Class start
            //
            cout<<"\n\tInvokeFirstEx create instance" << endl;
            jmethodID cls_constructor = env->GetMethodID(cls, "<init>", "()V");

            if (cls_constructor != 0) {             
                obj = env->NewObject(cls, cls_constructor, "()V");
                cout<<"\t\tstart calling method" << endl;
                mid = env->GetMethodID(cls, "AddFunc", "(II)I"); 
                if (mid != 0)
                {
                    result = env->CallIntMethod(obj, mid, 10, 20);
                    cout<<"\t\tresult: " << result << endl;
                }
                else
                {
                    printf("mid error\n");
                    return;
                }
            }       
        }
        else 
        {
            printf("Can't find class\n");
            return;
        }

        jvm->DestroyJavaVM();
        cout<<"\nJVM Destroyed!!"<<endl;
    }

}


## ================================ ##
#pragma comment(lib, "jvm.lib")

Because of this, your program is statically linked against jvm.lib . 因此,您的程序与jvm.lib静态链接。 That means that the jvm.dll must be somewhere on the DLL search path (current directory, C:\\Windows\\System32, %PATH%, ...) when your application is started. 这意味着在启动应用程序时, jvm.dll必须位于DLL搜索路径上(当前目录,C:\\ Windows \\ System32,%PATH%,...)。 Probably the jvm.dll is somewhere on your %PATH% and so the application works. jvm.dll可能位于%PATH%上的某个位置,因此该应用程序可以运行。 But as you also noticed, it's usually not like that. 但是,正如您还注意到的那样,通常情况并非如此。 So you have to use a different approach: Loading the library manually. 因此,您必须使用另一种方法:手动加载库。

I have written a detailed explanation on that in another answer . 在另一个答案中对此做了详细的解释。 That should be exactly what you need, you just have to replace all the throw gcnew System::ComponentModel::Win32Exception with your own error handling, since you're not using C++/CLI. 那应该正是您所需要的,因为您没有使用C ++ / CLI,您只需要用自己的错误处理替换所有throw gcnew System::ComponentModel::Win32Exception

Edit: Instead of RegGetValue , you could use RegQueryValueEx : 编辑:代替RegGetValue ,您可以使用RegQueryValueEx

RegQueryValueEx(jKey, TEXT("CurrentVersion"), NULL, NULL, versionString, &bufsize);

But if you take a look at the documentation of that function, you'll see that you should add a null terminator: 但是,如果您看一下该函数的文档 ,就会发现应该添加一个空终止符:

if (bufsize <= (16 * sizeof TCHAR)) // or whatever the buffer size is
    versionString[bufsize] = TEXT('\0');
else // error: buffer overflow

How would I make it be run on other normal PCs that has no JDK or MSVC? 如何使它在没有JDK或MSVC的其他普通PC上运行? because normal users definitely do not own JDK.. 因为普通用户绝对不拥有JDK。

They won't need JDK, installing JRE on clients is enough. 他们不需要JDK,在客户端上安装JRE就足够了。 But they definitely need a means to access jvm.dll (by adding its path to PATH environment varialble explained here ). 但他们绝对需要的手段来访问的jvm.dll(通过增加其路径PATH环境varialble解释这里 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM