Das Verhalten von extern "C"
-
Hallo,
ich habe gerade mehrere Stunden daran gesessen, den MinGW g++ compiler C-kompatible Symbole erzeugen zu lassen.
Das C++ Mangling Verhalten gewöhnt man ja dem Compiler mit extern "C" ab. Der MinGW zeigt da einen für meinen Geschmack etwas seltsames Verhalten:
Ich habe mit Java´s JNI gebastelt, und da ist das ja so, dass einem die C Header autogeneriert werden.
Java erzeugt mit so etwas, wichtig ist hier eigentlich nur dass "extern".
#ifdef __cplusplus extern "C" { #endif /* * Class: Renderer_RenderDevice * Method: createDisplay * Signature: (IIZ)V */ JNIEXPORT void JNICALL Java_Renderer_RenderDevice_createDisplay (JNIEnv *, jclass, jint, jint, jboolean); /* * Class: Renderer_RenderDevice * Method: setTitle * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_Renderer_RenderDevice_setTitle (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endifWenn ich nun auf diese Weise eine Implementierung angebe, erzeugt der MinGW trotzdem falsche Symbole. (Immer noch C++)
JNIEXPORT void JNICALL Java_Renderer_RenderDevice_createDisplay (JNIEnv* env, jobject o, jint width, jint height, jboolean fullscreen) { std::cout << "Wahoo: " << width << "," << height << std::endl; }Ich fand es dann auch recht logisch export "C" den Funktionsdefinitionen voranzustellen - hier kommt es ja schliesslich drauf an, nur gab es dann die Fehlermeldung:
RenderDevice.cc:14: error: declaration of C function `void Java_Renderer_RenderDevice_createDisplay(JNIEnv*, _jobject*, jint, jint, jboolean)' conflicts with ../RenderDevice.h:16: error: previous declaration `void Java_Renderer_RenderDevice_createDisplay(JNIEnv*, _jclass*, jint, jint, jboolean)' hereAngeblich sind die Deklarationen verschieden... es sind aber beide mit extern "C" definiert - also gleich.
Wenn ich nun das extern "C" aus den headern streiche, klappt alles korrekt.
Also alles kein Problem - es läuft, nur
1.) Verstehe ich das nicht
2.) Muss ich jedesmal das extern "C" streichen, wenn die header neu generiert werden ? Es wäre ja seltsam, wenn Suns header generell nicht funktionieren würde.Ist das ein Nichtstandart-Verhalten von MinGW ? Oder gibt es eine Lösung ohne die Header zu verändern ?
Ich hoffe jemand von euch kann da etwas Licht reinbringen,
Danke!!!
Frederick
-
kann es sein das die typen
RenderDevice.cc:14: error: declaration of C function `void Java_Renderer_RenderDevice_createDisplay(JNIEnv*, _jobject*, jint, jint, jboolean)' conflicts with
../RenderDevice.h:16: error: previous declaration `void Java_Renderer_RenderDevice_createDisplay(JNIEnv*, _jclass*, jint, jint, jboolean)' here
unteschiedlich sind?
-
hab letzt mit mingw ne jni lib bauen wollen und trotz linker options wie --kill-at konnt ich ihn nicht dazu bewegen, die symbole rauszukicken. hab mir dann beholfen, indem ich JNICALL rausgeschmissen hab und __declspec(dllexport) verwendete.
achso, und ja, die beiden methoden werden dieselbe signatur haben, wenn du die dekorationen streichst. vielleicht ists in deinem fall dann besser, nen mapping zu verwenden.
-
kann es sein das die typen
...
unteschiedlich sind?
Oh nein - wie dämlich 
Booar es war einfach zu spät gestern nacht. - Läuft jetzt alles prima.
Keine Ahnung wie der Fehler da reingerutscht ist... ich hab ja Cut`n´Paste
aus dem Header gemacht.hab letzt mit mingw ne jni lib bauen wollen und trotz linker options wie --kill-at konnt ich ihn nicht dazu bewegen, die symbole rauszukicken
Das einzige was --kill-at macht ist ein @n von den Symbolen zu entfernen, wobei
n eine Zahl ist, die angibt wieviel Speicher die Funktion auf dem Stack benötigt, das ist aber nur ein Schritt, das C++mangling bekommst dadurch nicht weg. Schau dir mal http://wyw.dcweb.cn/stdcall.htm dazu an, das hat mir ganz gut geholfen.
Bei mir hat es --add-stdcall-alias getan, aber das hast du ja wahrscheinlich auch probiert. Das Mangling verschwindet nur, wenn man die Funktionsdefinitionen in einen extern "C" Block packt. Ist vielleicht das gleiche wie __declspec(dllexport). Probier mal aus - bei mir klappt das so.
Achja und ich verwende noch -D_JNI_IMPLEMENTATION. Hab aber keine Ahnung was das tut.Jippey - jetzt klappt endlich alles.