2017-06-21 151 views
0

我有一個由Jet excelsior生成的.dll,我試圖從他們生成的調用dll中提取類。我正在按照他們原來在c中完成的示例腳本。儘管經過數小時的研究和排除故障,我無法使LoadLibrary調用開始工作。我正在運行Visual Studio 2017社區做一個空白的C++項目。這裏是我的調用和調試信息的一小部分,我已經能夠得到。任何解決方案或調試的建議是值得歡迎的,因爲我越來越絕望了,還對我的C++使用任何技巧是值得歡迎的,因爲我還是個新手:C++ LoadLibrary()導致程序退出

1. HINSTANCE test = LoadLibrary(L"C:\\Full Path\\myDll.dll"); 
2. //Code exits before reaching this point. 
3. int er = (int)GetLastError(); 

是的,我已經試過我的DLL移動到我的項目目錄,只是調用文件名稱。 不幸的是,我看不到getlasterror返回的內容,因爲代碼崩潰。 調試時,在執行第1行之前。其擴展信息是:
Name: test Value: 0xcccccccc{unused=???} unused <Unable to read memory>
我認爲這是無關緊要的,因爲它沒有實際執行?
以下是完整的代碼,如果它正好是相關的(它在底部未能在年初的main():

#include "stdafx.h" 
#include <string> 
#include <windows.h> 
#include <iostream> 
#include <C:\Program Files (x86)\Java\jdk1.8.0_131\include\jni.h> 

HINSTANCE loadDll(LPCWSTR name) 
{ 
    HINSTANCE hDll = LoadLibrary(name); 
    int thing = (int)GetLastError(); 
    if (!hDll) { 
     thing = (int)GetLastError(); 
     printf("Unable to load %s\n", name); 
     exit(1); 
    } 

    printf("%s loaded\n", name); 

    return hDll; 
} 

typedef jint(JNICALL * JNI_GetDefaultJavaVMInitArgs_func) (void *args); 
typedef jint(JNICALL * JNI_CreateJavaVM_func) (JavaVM **pvm, void **penv, void *args); 

/* 
* Initialize JET run-time. 
*/ 
void initJavaRT(HINSTANCE myDllHandle, JavaVM** pjvm, JNIEnv** penv) 
{ 
    JavaVMInitArgs args; 
    JNI_GetDefaultJavaVMInitArgs_func JNI_Init_Args = (jint(JNICALL *) (void *args)) GetProcAddress(myDllHandle, "JNI_GetDefaultJavaVMInitArgs"); 
    JNI_CreateJavaVM_func JNI_Create_VM = (jint(JNICALL *) (JavaVM **pvm, void **penv, void *args)) GetProcAddress(myDllHandle, "JNI_CreateJavaVM"); 

    if (!JNI_Init_Args) { 
     std::cerr << "!JNI_Init_Args\n"; 
     printf("%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n", dllName); 
     exit(1); 
    } 

    if (!JNI_Create_VM) { 
     printf("%s doesn't contain public JNI_CreateJavaVM\n", dllName); 
     exit(1); 
    } 

    memset(&args, 0, sizeof(args)); 

    /*args.version = JNI_VERSION_1_2; 
    if (JNI_GetDefaultJavaVMInitArgs_func(&args) != JNI_OK) { 
     printf("JNI_GetDefaultJavaVMInitArgs() failed with result %d\n", JNI_GetDefaultJavaVMInitArgs_func(&args)); 
     exit(1); 
    }*/ 

    /* 
    * NOTE: no JVM is actually created 
    * this call to JNI_CreateJavaVM is intended for JET RT initialization 
    */ 
    /*if (JNI_CreateJavaVM_func(pjvm, (void **)penv, &args) != JNI_OK) { 
     printf("JNI_CreateJavaVM() failed with result %d\n", JNI_CreateJavaVM_func(pjvm, (void **)penv, &args)); 
     exit(1); 
    }*/ 

    printf("JET RT initialized\n"); 
    fflush(stdout); 
} 


/* 
* Look for class. 
*/ 
jclass lookForClass(JNIEnv* env, char* name) 
{ 
    jclass clazz = env->FindClass(name); 

    if (!clazz) { 
     printf("Unable to find class %s\n", name); 
     exit(1); 
    } 

    printf("Class %s found\n", name); 
    fflush(stdout); 

    return clazz; 
} 


/* 
* Create an object and invoke the "ifoo" instance method 
*/ 
void invokeInstanceMethod(JNIEnv* env, jclass myClassInDll) 
{ 
    jmethodID MID_init, MID_ifoo; 
    jobject obj; 

    MID_init = env->GetMethodID(myClassInDll, "<init>", "()V"); 
    if (!MID_init) { 
     printf("Error: MyClassInDll.<init>() not found\n"); 
     return; 
    } 

    obj = env->NewObject(myClassInDll, MID_init); 
    if (!obj) { 
     printf("Error: failed to allocate an object\n"); 
     return; 
    } 

    MID_ifoo = env->GetMethodID(myClassInDll, "ifoo", "()V"); 

    if (!MID_ifoo) { 
     printf("Error: MyClassInDll.ifoo() not found\n"); 
     return; 
    } 

    env->CallVoidMethod(obj, MID_ifoo); 
} 



/* 
* Invoke the "foo" static method 
*/ 
void invokeStaticMethod(JNIEnv* env, jclass myClassInDll) 
{ 
    jmethodID MID_foo; 

    MID_foo = env->GetStaticMethodID(myClassInDll, "parse", "()V"); 
    if (!MID_foo) { 
     printf("\nError: MyClassInDll.foo() not found\n"); 
     return; 
    } 

    env->CallStaticVoidMethod(myClassInDll, MID_foo); 
} 


void finalizeJavaRT(JavaVM* jvm) 
{ 
    jvm->DestroyJavaVM(); 
} 


int main() 
{ 
    //Actually just trouble shooting code, not used in full program 
    HINSTANCE test = LoadLibrary(L"C:\\Full Path\\stgNativeProject.dll"); 
    int er = (int)GetLastError(); 

    //Actual program code 
    HINSTANCE myDllHandle; 
    JNIEnv *env; 
    JavaVM *jvm; 
    jclass myClassInDll; 

    /* 
    * First of all, load required component. 
    * By the time of JET initialization, all components should be loaded. 
    */ 
    std::cerr << dllName << "\n"; 
    myDllHandle = loadDll(dllName); 

    /* 
    * Initialize JET run-time. 
    * The handle of loaded component is used to retrieve Invocation API. 
    */ 
    initJavaRT(myDllHandle, &jvm, &env); 

    /* 
    * Look for class. 
    */ 
    myClassInDll = lookForClass(env, "MyClassInDll"); 

    /* 
    * Create an object and invoke instance method. 
    */ 
    invokeInstanceMethod(env, myClassInDll); 

    /* 
    * Invoke static method. 
    */ 
    invokeStaticMethod(env, myClassInDll); 

    /* 
    * Finalize JET run-time. 
    */ 
    finalizeJavaRT(jvm); 

    return 0; 
} 
+0

如果你打算這麼快就downvote,至少給我一個改進p的方法租約和謝謝。 –

+0

0xcccccccc =未初始化的堆棧內存:https://stackoverflow.com/a/127404/487892 – drescherjm

+0

LoadLibrary是否應該在被調用時處理?認爲這只是因爲它還沒有被實際執行 –

回答

0

我的問題的解決方法比較簡單,我測試的一個工具叫噴氣機。 Excelsior將預編譯我的java代碼以供本地使用。該實用程序創建了一個用於C++或c項目的.dll。我遇到的問題是調用dll需要與Jet運行時一起打包。檢查文檔here。如果你已經下載Jet,Jet樣本調用dlls/cmain將會對你最有幫助。