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;
}