1

I have a .dll generated by Jet excelsior which I am trying to pull classes from their generated invocation dll. I was following their example script originally done in c. Despite hours of research and troubleshooting I can not get the beginning LoadLibrary call to work. I am running visual studio 2017 community doing a blank c++ project. Here is my call and the little bit of debug info I have been able to get. Any solutions or debugging advice is welcome as I am becoming desperate, also any tips on my c++ usage is welcome as I am still a novice:

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

Yes, I have tried moving my dll to my project directory and just calling the file name. Unfortunately I cannot see what the getlasterror returns because the code crashes. When debugging, before Line 1 gets executed. Its expanded info is:
Name: test Value: 0xcccccccc{unused=???} unused <Unable to read memory>
I assume that is irrelevant because It has not actually been executed?
Here is the full code if it happens to be relevant (It fails at the bottom In the beginning of 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;
}
Zannith
  • 429
  • 4
  • 21
  • If your going to downvote so quickly, at least give me a way to improve please and thank you. – Zannith Jun 21 '17 at 16:59
  • 0xcccccccc = uninitialized stack memory: https://stackoverflow.com/a/127404/487892 – drescherjm Jun 21 '17 at 18:52
  • Isn't LoadLibrary supposed to take care of that upon being called? Figured that was just because it had not actually been executed yet – Zannith Jun 21 '17 at 20:30
  • You are correct. If LoadLibrary would have finished then `test` would have been initialized. I believe your dll is the problem. – drescherjm Jun 21 '17 at 20:34
  • Yes it is, funny thing, from debugging in the IDE i could not get any helpful errors. I ran the built exe however and the jet internal runtime told me the reason it is not working. Which has to do with having to package the dll with whatever source file is accessing it when building the project and requires it be built from jet. This makes debugging and editing issues within reasonable time next to impossible – Zannith Jun 21 '17 at 20:44

1 Answers1

0

The solution to my problem is relatively simple. I am testing a utility called Jet Excelsior to precompile my java code for native use. This utility creates a .dll for use in c++ or c projects. The issue I was having is that it is required for the invocation dll to be packed with Jet Pack along with the Jet runtime. Check the docs on it here. The Jet sample invocation dlls/ cmain will be the most helpful to you if you have downloaded Jet.

Zannith
  • 429
  • 4
  • 21