Java 初始化VM时出错,无法加载本机库:Can';找不到依赖库[编译C文件,JNI]

Java 初始化VM时出错,无法加载本机库:Can';找不到依赖库[编译C文件,JNI],java,c++,jvm,java-native-interface,reverse,Java,C++,Jvm,Java Native Interface,Reverse,根据本教程,我正在实现一个“反向”JNI以从C调用Java:。每当我编译文件“CTest.cpp”并在Windows命令提示符或Visual Studio中运行“CTest.exe”时,总会收到以下错误: VM初始化期间出错无法加载本机库:找不到依赖库 我知道还有类似的问题:我已经看到了它们并应用了建议(比如将我的jvm.dll和jvm.lib路径链接到PATH环境变量)。我还通过Visual Studio在文件属性中添加了jvm.dll位置。我真的需要帮助——我已经在这上面呆了几天了。谢谢你抽

根据本教程,我正在实现一个“反向”JNI以从C调用Java:。每当我编译文件“CTest.cpp”并在Windows命令提示符或Visual Studio中运行“CTest.exe”时,总会收到以下错误:

VM初始化期间出错无法加载本机库:找不到依赖库

我知道还有类似的问题:我已经看到了它们并应用了建议(比如将我的jvm.dll和jvm.lib路径链接到PATH环境变量)。我还通过Visual Studio在文件属性中添加了jvm.dll位置。我真的需要帮助——我已经在这上面呆了几天了。谢谢你抽出时间

CTest.cpp如下所示:

#包括“StdAfx.h”
#包括
#包括
#包括
#定义路径_分隔符“;”/*在Solaris上将其定义为“:”*/
#定义用户_CLASSPATH”“/*其中Prog.class是*/
结构控制细节
{
int-ID;
字符名[100];
char-IP[100];
国际港口;
};
结构工单
{
char-sumSerialId[20];
字符存取号[18];
字符操作类型[4];
字符生效日期[24];
char-fetchFlag[2];
原因[456];
字符访问源[100];
};
JNIEnv*创建虚拟机(JavaVM**jvm){
JNIEnv*env;
JavaVMInitArgs vm_args;
JavaVMOption选项;
options.optionString=“-Djava.class.path=C:\\Users\\My Name\\Downloads\\src\u CJNIJava\\Java src\\TestStruct”;//Java源代码的路径
vm_args.version=JNI_version_1_8;//JDK version。这表示版本1.8
vm_args.nOptions=1;
vm_args.options=&options;
vm_args.ignoreunrecogned=0;
int ret=JNI_CreateJavaVM(jvm,(void**)&env和vm_args);
如果(ret<0)
printf(“\n无法启动JVM\n”);
返回环境;
}
int main(int argc,char*argv[])
{
JNIEnv*env;
JavaVM*jvm;
env=创建虚拟机(&jvm);
if(env==NULL)
返回1;
结构控制详细信息;
ctrlDetail.ID=11;
strcpy(ctrlDetail.Name,“HR-HW”);
strcpy(ctrlDetail.IP,“10.32.164.133”);
ctrlDetail.Port=9099;
printf(“在C中创建的结构具有以下值:\nID:%d\n名称:%s\n IP:%s\n端口:%d\n”,ctrlDetail.ID,ctrlDetail.Name,ctrlDetail.IP,ctrlDetail.Port);
/********************************************************/
结构工单WO[2];
strcpy(WO[0].sumSerialId,“2000”);
strcpy(WO[0]。访问编号,“2878430”);
strcpy(WO[0].actionType,“04”);
strcpy(WO[0].生效日期,“25-12-2007 12:20:30 PM”);
strcpy(WO[0].fetchFlag,“0”);
strcpy(WO[0]。原因为“执行成功”);
strcpy(WO[0].accessSource,“PMS”);
strcpy(WO[1].sumSerialId,“1000”);
strcpy(WO[1]。访问编号,“2878000”);
strcpy(WO[1]。动作类型,“T4”);
strcpy(WO[1].生效日期,“25-12-2007 11:20:30 PM”);
strcpy(WO[1].fetchFlag,“0”);
strcpy(WO[1]。原因,“”);
strcpy(WO[1].accessSource,“RMS”);
jclass clsH=NULL;
jclass clsC=NULL;
jclass clsW=NULL;
jclass clsR=NULL;
jmethodID midMain=NULL;
jmethodID midcall=NULL;
jmethodID midDispStruct=NULL;
jmethodID MiddisStructArr=NULL;
jmethodID midRetObjFunc=NULL;
jmethodID midCtrlDetConst=NULL;
jmethodID midWoConst=NULL;
jobject jobjDet=NULL;
jobject jobjRetData=NULL;
jobjectArray jobjWOArr=NULL;
//获得课程
clsH=env->FindClass(“HelloWorld”);
clsC=env->FindClass(“控制细节”);
clsW=env->FindClass(“工作订单”);
//获取方法ID
如果(clsH!=NULL)
{
midMain=env->GetStaticMethodID(clsH,“main”,“([Ljava/lang/String;)V”);
midCalling=env->GetStaticMethodID(clsH,“TestCall”,“Ljava/lang/String;)V);
midDispStruct=env->GetStaticMethodID(clsH,“DisplayStruct”,“LControlDetail;”)I);
midDispStructArr=env->GetStaticMethodID(clsH,“DisplayStructArray”,“([LWorkOrder;)V”);
midRetObjFunc=env->GetStaticMethodID(clsH,“ReturnObjFunc”,“Ljava/lang/Object;”);
}
其他的
{
printf(“\n无法找到请求的类\n”);
}
如果(clsC!=NULL)
{
//获取ControlDetail的构造函数ID
midcrldtconst=env->GetMethodID(clsC,“,”(ILjava/lang/String;Ljava/lang/String;I)V);
}
其他的
{
printf(“\n无法找到请求的类\n”);
}
如果(clsW!=NULL)
{
//获取WorkOrder的构造函数ID
midWoConst=env->GetMethodID(clsW,“,”(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V);
}
其他的
{
printf(“\n无法找到请求的类\n”);
}
/************************************************************************/
/*现在我们将使用方法ID调用函数*/
/************************************************************************/
if(midMain!=NULL)
env->CallStaticVoidMethod(clsH,midMain,NULL);//调用main方法。
if(中间调用!=NULL)
{
jstring StringArg=env->NewStringUTF(“\nTestCall:从C程序调用\n”);
//调用另一个静态方法并传递字符串类型参数
env->CallStaticVoidMethod(clsH、中间调用、StringArg);
}
printf(“\n正在调用DisplayStruct\n”);
if(midDispStruct!=NULL)
{
如果(clsC!=NULL&&MIDCTRLEDCONST!=NULL)
{
jstring StringArgName=env->NewStringUTF(ctrlDetail.Name);
jstring StringArgIP=env->NewStringUTF(ctrlDetail.IP);
//创建ControlDetail的对象。
jobjDet=env->NewObject(clsC,midCtrlDetConst,(jint)ctrlDetail.ID,StringArgName,StringArgIP,(jint)ctrlDetail.Port);
}
if(jobjDet!=NULL&&midDispStruct!=NULL)
环境-
#include "StdAfx.h"
#include <stdio.h>
#include <jni.h>
#include <string.h>

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH "." /* where Prog.class is */

struct ControlDetail
{
    int ID;
    char Name[100];
    char IP[100];
    int Port;
};

struct WorkOrder
{
    char        sumSerialId[20];
    char        accessNumber[18];
    char        actionType[4];
    char        effectiveDate[24];
    char        fetchFlag[2];
    char        reason[456];
    char        accessSource[100];
};

JNIEnv* create_vm(JavaVM ** jvm) {

    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options;
    options.optionString = "-Djava.class.path=C:\\Users\\My Name\\Downloads\\src_CJNIJava\\Java Src\\TestStruct"; //Path to the java source code
    vm_args.version = JNI_VERSION_1_8; //JDK version. This indicates version 1.8
    vm_args.nOptions = 1;
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = 0;

    int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
    if (ret < 0)
        printf("\nUnable to Launch JVM\n");
    return env;
}

int main(int argc, char* argv[])
{
    JNIEnv *env;
    JavaVM * jvm;
    env = create_vm(&jvm);
    if (env == NULL)
        return 1;

    struct ControlDetail ctrlDetail;
    ctrlDetail.ID = 11;
    strcpy(ctrlDetail.Name, "HR-HW");
    strcpy(ctrlDetail.IP, "10.32.164.133");
    ctrlDetail.Port = 9099;

    printf("Struct Created in C has values:\nID:%d\nName:%s\n IP:%s\nPort:%d\n", ctrlDetail.ID, ctrlDetail.Name, ctrlDetail.IP, ctrlDetail.Port);

    /********************************************************/
    struct WorkOrder WO[2];
    strcpy(WO[0].sumSerialId, "2000");
    strcpy(WO[0].accessNumber, "2878430");
    strcpy(WO[0].actionType, "04");
    strcpy(WO[0].effectiveDate, "25-12-2007 12:20:30 PM");
    strcpy(WO[0].fetchFlag, "0");
    strcpy(WO[0].reason, "Executed Successfully");
    strcpy(WO[0].accessSource, "PMS");
    strcpy(WO[1].sumSerialId, "1000");
    strcpy(WO[1].accessNumber, "2878000");
    strcpy(WO[1].actionType, "T4");
    strcpy(WO[1].effectiveDate, "25-12-2007 11:20:30 PM");
    strcpy(WO[1].fetchFlag, "0");
    strcpy(WO[1].reason, "");
    strcpy(WO[1].accessSource, "RMS");


    jclass clsH = NULL;
    jclass clsC = NULL;
    jclass clsW = NULL;
    jclass clsR = NULL;
    jmethodID midMain = NULL;
    jmethodID midCalling = NULL;
    jmethodID midDispStruct = NULL;
    jmethodID midDispStructArr = NULL;
    jmethodID midRetObjFunc = NULL;
    jmethodID midCtrlDetConst = NULL;
    jmethodID midWoConst = NULL;

    jobject jobjDet = NULL;
    jobject jobjRetData = NULL;
    jobjectArray jobjWOArr = NULL;

    //Obtaining Classes
    clsH = env->FindClass("HelloWorld");
    clsC = env->FindClass("ControlDetail");
    clsW = env->FindClass("WorkOrder");

    //Obtaining Method IDs
    if (clsH != NULL)
    {
        midMain = env->GetStaticMethodID(clsH, "main", "([Ljava/lang/String;)V");
        midCalling = env->GetStaticMethodID(clsH, "TestCall", "(Ljava/lang/String;)V");
        midDispStruct = env->GetStaticMethodID(clsH, "DisplayStruct", "(LControlDetail;)I");
        midDispStructArr = env->GetStaticMethodID(clsH, "DisplayStructArray", "([LWorkOrder;)V");
        midRetObjFunc = env->GetStaticMethodID(clsH, "ReturnObjFunc", "()Ljava/lang/Object;");
    }
    else
    {
        printf("\nUnable to find the requested class\n");
    }
    if (clsC != NULL)
    {
        //Get constructor ID for ControlDetail
        midCtrlDetConst = env->GetMethodID(clsC, "<init>", "(ILjava/lang/String;Ljava/lang/String;I)V");
    }
    else
    {
        printf("\nUnable to find the requested class\n");
    }

    if (clsW != NULL)
    {
        //Get Constructor ID for WorkOrder
        midWoConst = env->GetMethodID(clsW, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
    }
    else
    {
        printf("\nUnable to find the requested class\n");
    }

    /************************************************************************/
    /* Now we will call the functions using the their method IDs            */
    /************************************************************************/
    if (midMain != NULL)
        env->CallStaticVoidMethod(clsH, midMain, NULL); //Calling the main method.

    if (midCalling != NULL)
    {
        jstring StringArg = env->NewStringUTF("\nTestCall:Called from the C Program\n");
        //Calling another static method and passing string type parameter
        env->CallStaticVoidMethod(clsH, midCalling, StringArg);
    }

    printf("\nGoing to Call DisplayStruct\n");
    if (midDispStruct != NULL)
    {
        if (clsC != NULL && midCtrlDetConst != NULL)
        {
            jstring StringArgName = env->NewStringUTF(ctrlDetail.Name);
            jstring StringArgIP = env->NewStringUTF(ctrlDetail.IP);

            //Creating the Object of ControlDetail.
            jobjDet = env->NewObject(clsC, midCtrlDetConst, (jint)ctrlDetail.ID, StringArgName, StringArgIP, (jint)ctrlDetail.Port);
        }

        if (jobjDet != NULL && midDispStruct != NULL)
            env->CallStaticIntMethod(clsH, midDispStruct, jobjDet); //Calling the method and passing ControlDetail Object as parameter
    }
    //Calling a function from java and passing Structure array to it.
    printf("\n\nGoing to call DisplayStructArray From C\n\n");
    if (midDispStructArr != NULL)
    {
        if (clsW != NULL && midWoConst != NULL)
        {
            //Creating the Object Array that will contain 2 structures.
            jobjWOArr = (jobjectArray)env->NewObjectArray(2, clsW, env->NewObject(clsW, midWoConst, env->NewStringUTF(""), env->NewStringUTF(""), env->NewStringUTF(""),
                env->NewStringUTF(""), env->NewStringUTF(""), env->NewStringUTF(""), env->NewStringUTF("")));
            //Initializing the Array
            for (int i = 0; i<2; i++)
            {
                env->SetObjectArrayElement(jobjWOArr, i, env->NewObject(clsW, midWoConst, env->NewStringUTF(WO[i].sumSerialId),
                    env->NewStringUTF(WO[i].accessNumber),
                    env->NewStringUTF(WO[i].actionType),
                    env->NewStringUTF(WO[i].effectiveDate),
                    env->NewStringUTF(WO[i].fetchFlag),
                    env->NewStringUTF(WO[i].reason),
                    env->NewStringUTF(WO[i].accessSource)));
            }
        }
        //Calling the Static method and passing the Structure array to it.
        if (jobjWOArr != NULL && midDispStructArr != NULL)
            env->CallStaticVoidMethod(clsW, midDispStructArr, jobjWOArr);
    }
    //Calling a Static function that return an Object
    if (midRetObjFunc != NULL)
    {
        //Calling the function and storing the return object into jobject type variable
        //Returned object is basically a structure having two fields (string and integer)
        jobjRetData = (jobject)env->CallStaticObjectMethod(clsH, midRetObjFunc, NULL);
        //Get the class of object
        clsR = env->GetObjectClass(jobjRetData);
        //Obtaining the Fields data from the returned object
        jint nRet = env->GetIntField(jobjRetData, env->GetFieldID(clsR, "returnValue", "I"));
        jstring jstrLog = (jstring)env->GetObjectField(jobjRetData, env->GetFieldID(clsR, "Log", "Ljava/lang/String;"));
        const char *pLog = env->GetStringUTFChars(jstrLog, 0);

        printf("\n\nValues Returned from Object are:\nreturnValue=%d\nLog=%s", nRet, pLog);
        //After using the String type data release it.
        env->ReleaseStringUTFChars(jstrLog, pLog);
    }
    //Release resources.
    int n = jvm->DestroyJavaVM();
    return 0;
}