【问题标题】:How to let any users run .exe program that reads java methods from its c++ code?如何让任何用户运行从其 c++ 代码中读取 java 方法的 .exe 程序?
【发布时间】:2013-08-19 21:01:32
【问题描述】:

这里是源代码的 zip 文件: http://cfile218.uf.daum.net/attach/254F2D4F5211EF93107910

,或者底部可见的源代码。

我刚刚在我的 PC 上编译并运行它:在调试和发布模式下都运行良好。

但是,如果我尝试在另一台 PC 上运行它(安装了 Windows XP),它会显示一个错误,指出我没有“jvm.dll”,因此无法运行它。

因此我从地址“http://java.com/en/download/index.jsp”安装了java并运行了它。但是,它仍然说同样的错误。

这是我的问题....

如何让它在其他没有 JDK 或 MSVC 的普通 PC 上运行?因为普通用户肯定没有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;
    }

}


## ================================ ##

【问题讨论】:

  • 听起来像是配置问题 - 很可能安装程序没有为“所有用户”安装。如果您在计算机上拥有管理员权限,则很可能只是将一些环境变量从“每个用户”设置移动到“每个系统”设置。
  • Cannot load JVM 的可能副本

标签: java c++ java-native-interface


【解决方案1】:
#pragma comment(lib, "jvm.lib")

因此,您的程序与jvm.lib 静态链接。这意味着当您的应用程序启动时,jvm.dll 必须位于 DLL 搜索路径(当前目录、C:\Windows\System32、%PATH%、...)上的某个位置。 jvm.dll 可能在您的 %PATH% 上的某个位置,因此该应用程序可以正常工作。但正如您也注意到的那样,通常情况并非如此。所以你必须使用不同的方法:手动加载库。

我已经写了关于in another answer的详细解释。这应该正是您所需要的,您只需将所有 throw gcnew System::ComponentModel::Win32Exception 替换为您自己的错误处理,因为您没有使用 C++/CLI。

编辑:你可以使用RegQueryValueEx,而不是RegGetValue

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

但是如果你看一下那个函数的documentation,你会发现你应该添加一个空终止符:

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

【讨论】:

  • 您好 main-- 我几乎成功了,但是在 Windows XP 上还有另一个错误提示“无法从 ADVAPI32.dll 找到 regGetValueA”。我搜索了它,Windows XP 不支持 regGetValueA 方法.. 是否有替代这些功能以使其在 Win xp 上运行?谢谢你帮助我,你的答案很棒!
  • 您的问题的一部分是否仍然没有答案,或者您为什么没有选择答案?
  • 我刚刚做了。也许我现在必须为所有其他问题选择已回答。
【解决方案2】:

如何让它在其他没有 JDK 或 微软?因为普通用户肯定没有JDK..

他们不需要 JDK,在客户端上安装 JRE 就足够了。但是他们肯定需要一种访问 jvm.dll 的方法(通过将其路径添加到 PATH 环境变量中,解释为 here)。

【讨论】:

    猜你喜欢
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多