Hjälp: Java Native Interface & C++

Permalänk
Medlem

Hjälp: Java Native Interface & C++

Om man söker i forumet efter JNI så får man upp en del trådar om vad jag håller på att försöka åstadkomma.

Jag försöker skapa en global keylistener för Java, för jag skriver ett program som kräver att en lyssnare som fungerar när applikationen ej är i fokus. Jag såg även möjligheten att lära mig JNI. Nu har jag spenderat mer eller mindre hela dagen med att lära mig hur det fungerar. Java sidan är skriven och konverterad till header-fil. Cpp-koden är omskriven för att passa ihop med JNI och alla stegen är gjorda fram till det sista. Att länka ihop output:en från C++ med Export-dokumentet för att bilda DLL-filen.

Cygwin+gcc(för att bygga DLL-filen):

gcc -shared -o passiveKeylistener.dll passiveKeylistener.o passiveKeylistener.def

Det ger i sin tur ett fel meddelande som har uppbyggnaden:

Cannot export Java_*packageName*_*className*_*functionName*: symbol not defined

Detta följt av ett par rader som hänvisar till minnesplatser på stacken, med meddelandet "undefined reference to....."
Hela loggen hittar ni här

Har någon stött på detta eller har en gissning om vart det kan ha gått fel? (Vill gärna lösa detta för att ha lärt mig hela metoden)
Jag tar gärna emot förslag på lättare lösningar, JNI-komplement osv, för framtida projekt.

Tack på förhand

Permalänk
Hedersmedlem

Överensstämmer .def-filens innehåll med .o-filens, och använder du extern "C"?

Permalänk
Medlem
Skrivet av Elgot:

Överensstämmer .def-filens innehåll med .o-filens, och använder du extern "C"?

Ja, använder extern C. Det enda jag är osäker på med .def-filen är om paketnamnet för Java-biten ska vara med.

Det ska väl bara vara?:

EXPORTS Java_packageName_className_functionName

Permalänk
Datavetare

Ditt problem verkar vara att länkaren inte hittar rätt bibliotek för C++ funktionerna ("string" funktioner i ditt fall).

Den JVM du använder, kör den under Cygwin eller direkt under Win32? D.v.s. använder du "java" och "javac" i Cygwin eller kör du med "java.exe" och "javac.exe" som installerats med t.ex. Oracles setup.exe?

Du använder just nu gcc för Cygwin, vilket förutsätter att du också använder Cygwin versionen av Java.

Om du kör med java.exe ska du endera använda MSVC (C/C++ kompilatorn i Visual Studio) eller MinGW versionen av gcc.

Sedan är det massor med saker som man gå fel när man exporterar C++ funktioner från en dll då C++ inte innehåller en binär-specifikation, i.e. en dll byggd med en kompilator kan med största sannolikhet inte används av en annan kompilator. Exportera bara C-funktioner då C även specificerar det binära formatet.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Ditt problem verkar vara att länkaren inte hittar rätt bibliotek för C++ funktionerna ("string" funktioner i ditt fall).

Den JVM du använder, kör den under Cygwin eller direkt under Win32? D.v.s. använder du "java" och "javac" i Cygwin eller kör du med "java.exe" och "javac.exe" som installerats med t.ex. Oracles setup.exe?

Du använder just nu gcc för Cygwin, vilket förutsätter att du också använder Cygwin versionen av Java.

Om du kör med java.exe ska du endera använda MSVC (C/C++ kompilatorn i Visual Studio) eller MinGW versionen av gcc.

Sedan är det massor med saker som man gå fel när man exporterar C++ funktioner från en dll då C++ inte innehåller en binär-specifikation, i.e. en dll byggd med en kompilator kan med största sannolikhet inte används av en annan kompilator. Exportera bara C-funktioner då C även specificerar det binära formatet.

Jag använder JVM under Win32 men gcc under Cygwin. Kan det vara felet?
Jag ska testa med MinGW nu hade jag tänkt.

Permalänk
Medlem

Nu har jag testat med MinGW och fick färre felmeddelande men finns fortfarande två.

passiveKeylistener.o:passiveKeylistener.cpp:(.text+0x51): undefined reference to `std::ios_base::Init::~Init()' passiveKeylistener.o:passiveKeylistener.cpp:(.text+0x72): undefined reference to `std::ios_base::Init::Init()'

LÖSNING:

g++ -shared -o passiveKeylistener.dll passiveKeylistener.o -Wl,--out-implib,passiveKeylistener.def