简体   繁体   中英

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

,or visible source code in the bottom.

I just compiled and ran it on my PC: worked fine in both debug and release mode.

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.

Therefore I installed java from the address " http://java.com/en/download/index.jsp " and runned it. 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? because normal users definitely do not own 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 . 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. Probably the jvm.dll is somewhere on your %PATH% and so the application works. 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.

Edit: Instead of RegGetValue , you could use 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? because normal users definitely do not own JDK..

They won't need JDK, installing JRE on clients is enough. But they definitely need a means to access jvm.dll (by adding its path to PATH environment varialble explained here ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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