Dll Import klappt nicht

Okay ich brauch noch mal Hilfe ^^
Ich bin schon ne ganze Ecke weiter, brauch allerdings jetzt folgendes:
Bisher sahen meine ausgelagerten Funktionen so aus:
C:
typedef BOOL (*MYFUNC)(void);
 
MYFUNC InstallHook;
MYFUNC UninstallHook;
Aufrufen etc. klappt auch gut ;)
Nun brauche ich aber Parameter für eine Funktion:

C:
MYFUNC UninstallHook;
MYFUNCEXT InstallHook;
typedef BOOL (*MYFUNCEXT)(int, JNIEnv *, jobject, jmethodID);
typedef BOOL (*MYFUNC)(void);
Sonst ist alles gleich allerdings wird:
C:
InstallHook = (MYFUNCEXT) GetProcAddress( hDll, "InstallHook" );
InstallHook gleich NULL..
Implementierung der Methode:
C:
DLLIMPORT BOOL InstallHook( int nrOfHotkeys, JNIEnv *env, jobject clazz, jmethodID mId)
Im Header
C:
DLLIMPORT BOOL InstallHook( int, JNIEnv *, jobject, jmethodID );
Was mach ich falsch?

Gruß
 
So .. hab das Problem nun etwas eingrenzen können.. und ehrlich gesagt verwirrt mich das ganz schön :confused:
Bisher hab ich die DLL mit dem Hookcode drin als C-Datei kompilieren lassen (DevC++ mit gcc).
Nun brauchte ich allerdings folgenden Aufruf:
C:
JNIEnv *env
.
.
env->CallVoidMethod( jniClass, jniMId, (jint) wParam, (jint)0, (jint)0 );
Das scheint aber in reinem C so nicht zu gehen (Compilerfehler irgendwas mit env sei kein union oder struct).
Also hab ich das ganze einfach als C++-Datei kompilieren lassen (und mir nichts bei gedacht) - und es funktionierte.

Allerdings ergeben sich daraus jetzt einige komische "Nebenwirkungen".
Zum einen heißt die öffentliche Funktion der DLL jetzt nicht mehr "InstallHook" sondern "_Z11InstallHookiP7JNIEnv_P8_jobjectP10_jMethodID"...

Aber ok, selbst das geht noch wenn man es weiß.. Nur wird beim Aufruf von LoadLibrary nicht mehr die DLLMain aufgerufen, was mein eigentliches Problem ist - Ich komme dann nicht mehr an den ModuleHandle..

Wie kann es sein das nur die Tatsache ob die Datei als C oder C++ kompiliert wird einen so gravierenden Unterschied ausmacht?

Gruß
 
javaprogger1987 hat gesagt.:
Wie kann es sein das nur die Tatsache ob die Datei als C oder C++ kompiliert wird einen so gravierenden Unterschied ausmacht?
Der C++ Compiler muß der Tatsache Rechnung tragen das man in C++ Funktionen überladen kann. Es darf aber eigentlich im Objektcode keine Symbole mit gleichem Namen geben. Daher verwendet ein C++ Compiler "name mangling" und fügt die Typen der Argumente und evtl. den namespace etc. dem Symbolnamen hinzu (was eine überladene Funktion dann wieder eindeutig macht).

Versuch mal das ganze wieder in C so aufzurufen:
C:
(*env)->CallVoidMethod( jniClass, jniMId, (jint) wParam, (jint)0, (jint)0 );
Gruß
 
Cool das klappt :D Vielen Dank nochmals :)
Gleich noch ne Frage hinterher :/
Und zwar brauch ich ne Funktion (GetJavaVM) die sich in der Library jvm.lib befindet..
Ich hab nun schon herausgefunden, dass man lib-Dateien mit gcc nicht verarbeiten kann und hab die in eine .a-Datei umgewandelt mit reimp.exe..
Allerdings bekomme ich immer noch den Fehler "dllmain.o(.text+0x4c):dllmain.c: undefined reference to `GetJavaVM'".
Hab das Verzeichnis wo die libjvm.a drin ist aber schon an allen möglichen Stellen angegeben.. Wie muss krieg ich das hin das der die findet? (Bzw. wie muss der Aufruf von dllwrap aussehen)?
Bisher
Code:
C:\Programme\Dev-Cpp\bin\dllwrap.exe --output-def libjnikeyhook.def --implib libjnikeyhook.a dllmain.o -L"C:/Programme/Dev-Cpp/lib" -L"C:/Programme/Java/jdk1.5.0_04/lib" -L"C:/Programme/Java/jdk1.5.0_04/lib/" -L"C:/Programme/Java/jdk1.5.0_04/jre/bin/client" --no-export-all-symbols --add-stdcall-alias -o jnikeyhook.dll

Vielen Dank nochmals für die bisherige Hilfe..

Gruß
 
Hallo!

nur ein Tipp am Rande: System-Hooks sollten nur so lange aktiviert bleiben wie die andere Applikation auch laeuft. Deshalb solltest du auch einen Hook-Unregister Mechanismus implementieren der entweder programmatisch von deiner Anwendung oder Beispielsweise ueber
void JNI_OnUnload(JavaVM *vm, void *reserved); von der JVM getriggert wird.

Gruss Tom
 
Also ich kann's hier leider nicht testen weil ich kein Java SDK installiert hab. Also hab ich mal etwas im Internet gesucht (http://www.inonit.com/cygwin/jni/invocationApi/archive.html)

So wie es aussieht brauchst du nur eine Import-Bibliothek mit
Code:
dlltool --input-def jvm.def --kill-at --dllname jvm.dll --output-lib libjvm.dll.a
erstellen und dann mit der erstellten (oder von der Seite heruntergeladenen) Datei linken:
Code:
gcc -mno-cygwin -o invoke.exe -I$jdk/include -I$jdk/include/win32 invoke.c -L. -ljvm

dllwrap scheint veraltet und nicht notwendig zu sein.

Gruß
 
@Tom Ja das mach ich auch schon, allerdings ist das mit OnUnload ne bessere Idee ;) Das werd ich wohl mal einbauen

@deepthroat Die Seite du du gepostet hast hatte ich auch schon gefunden, allerdings ist da das Problem, dass dort nur lediglich 3 Funktionen zur Verfügung stehen ich aber wesentlich mehr brauche..
Deshalb hab ich es so gemacht wie es hier steht:
http://www.mrunix.de/forums/showthread.php?t=44295

Aber ich werd das noch mal austesten.. dllwrap hab ich benutzt weil ich ja eine Dll haben möchte und keine .exe..

Gruß

//edit Also die Methode die ich gemacht hab scheint ähnlich, da ich die .def Datei nur hab erzeugen lassen (Hab also alle Funktionen drin).
Nur wie kompilier ich das mit gcc jetzt richtig in der Kommandozeile?
Der findet die jni.h nicht selbst wenn ich den Pfad mit -L oder -I angebe.. Ich blicks einfach nich :(
 
Zuletzt bearbeitet:
Wenn du eine dll herausbekommen möchtest mußt du eigentlich beim GCC nur die Option -shared angeben.

Header-Dateien sucht der GCC in allen Verzeichnissen die du mit -I (großes i) angegeben hast. Je nachdem wo du dein SDK installiert hast also z.B. -Ic:/java/sdk1.5/include

Gruß
 
Ok vielen Dank für die Geduld ;)
Ich weiß jetzt was los war, ich hab versucht
C:
GetJavaVM
aufzurufen, was Quatsch war, denn es musste lauten
C:
(*env)->GetJavaVM
..
Meine eigene Schuld, sorry ;)
Ab nun kann ich im Java Forum noch ein paar Leute nerven ;)

Gruß
 
Zurück