2010-03-17 5 views
3

Je gère projet JNI pour les compilateurs: MSVC++ 8.0 et 9.0, mon fichier cpp contient suivant la mise en œuvre: extern "C" { JNIEXPORT de JNICALL Java_context_ServiceProviderContext_StartServiceProvider (JNIEnv * env, JClass, jstring jspath) { ..... }extern "C" n'a pas d'effet dans msvC++ 9.0

Avec l'aide de l'utilitaire depends.exe je peux voir que MSVC 8.0 exporte avec succès la fonction comme il est prévu: Java_context_ServiceProviderContext_StartServiceProvider Mais la compilation sous MSVC 9.0 me rend fou il exp orts comme ignorer extern "C" du tout. depends.exe me montre: _Java_context_ServiceProviderContext_StartServiceProvider @ 12

Quelqu'un sait-il ce que exactement 9.0 projet qui provoque ce comportement?

+0

La description technique est que votre compilation 9.0 est un manquement de noms. C ne fait pas name-mangle (qui fait partie de ce que 'Extern C' dit au compilateur de faire). –

+0

@ Paul Nathan - alors, quelle est votre recommandation? – Dewfy

+0

Je n'ai pas de vraie réponse pour vous. Ça * sonne * comme un bug. Soit cela ou un drapeau doit être affirmé maintenant ... La seule chose que je peux penser à faire est de fouiller sur le MSDN et/ou d'appeler le support de Microsoft. –

Répondre

1

JNICALL est probablement #define JNICALL __stdcall. Changer la convention d'appel va corriger la décoration du nom, mais elle va horriblement (y compris silencieusement) casser JNI, car elle appellera une fonction en supposant __stdcall et obtenir quelque chose d'autre.

Est-ce que ça ne fonctionne pas? D'après ce que je peux google, il semble que la JVM sache comment décorer correctement les noms des fonctions.

+1

Vous avez raison, c'est __stdcall, mais JVM attend exactement Java_context_ServiceProviderContext_StartServiceProvider. S'il vous plaît noter que toutes les choses sont correctes sous MSVC 8.0, je suis assez sûr que ce problème apparaît lors de la migration du projet. – Dewfy

+1

Vous pouvez également lier manuellement le nom à l'aide du fichier .def. – MSN

0

C'est la convention d'appel __stdcall; vous avez besoin de __cdecl. Peut-être essayer d'ajouter __cdecl à la définition de votre fonction?

Vous pouvez également modifier la convention d'appel par défaut dans les paramètres du projet.

+1

Non, merci - JNI attend exactement __stdcall. Et 8.0 a réussi sans aucun problème. Et juste pour votre différence d'information entre __cdecl et __stdcall pas dans la décoration, mais dans l'ordre des paramètres. – Dewfy

+0

La seule différence entre __cdecl et __stdcall est de savoir qui est responsable de l'extraction des paramètres de la pile. Mais oui, la convention d'appel et la décoration du nom sont orthogonales entre elles. –

+0

+1. Je vote pour cela car cela a résolu le problème pour moi. Mon dll-export avec extern "C" était déformé jusqu'à ce que je supprime __stdcall et que le paramètre par défaut __cdecl entre en jeu. Si la convention d'appel en elle-même n'est pas l'essence de la solution dans ce cas, peut-être l'une des autres Les commentateurs aimeraient poster une nouvelle réponse éclairant pourquoi cela fonctionne. – sharkin