Importer une fonction depuis un dll externe [Résolu]

Rabbi Jakob 4 Messages postés vendredi 3 août 2007Date d'inscription 7 août 2007 Dernière intervention - 6 août 2007 à 16:58 - Dernière réponse : Rabbi Jakob 4 Messages postés vendredi 3 août 2007Date d'inscription 7 août 2007 Dernière intervention
- 7 août 2007 à 14:27
Bonjour,
Je programme en c++ sous visual studio 2005
J'ai un petit problème avec ma dll Je dispose d'une dll avec son fichier .lib. Je les ai mis tous les 2  dans le répertoire où se trouve le .exe de mon projet, et j'ai linké la librairie aux projet dans project dépendencies.
Mon problème est le suivant. J'appelle une fonction MaFonction dans ma dll MaDLL.dll.
MaFonction prend en argument une structure MaStructure. MaStructure et MaFonction sont définies dans le fichier header généré avec la dll, MaDll.h.
Si je fais extern "C" __declspec(dllimport) void MaFonction(MaStruct), et que je le place après #include <MaDll.h>, il me lance une erreur C2732, selon laquelle ma fonction est déjà définie ailleurs (ce que je conçois aisément puisqu'elle est dans le .h)
Seulement, si je ne place pas le extern "C" declspec(dllimport)... , et que je mets seulement le fichier .h, il me lance une erreur LNK2001, il ne trouve pas la fonction (unresolved external symbol) Pourtant la librairie est bien linkée. Je ne comprends vraiment pas, j'ai lu la msdn, j'ai fouillé un max de forum, j'ai essayé une autre fonction de la dll qui prend des types simples, et là c'est encore plus étrange
Si je fais le extern "C" _declspec double FonctionSimple (double, double), et que je place ça avant la déclaration des fichiers .h, la fonction sort le bon résultat. Si je le mets après le .h, il me ressort l'erreur C2732 (déjà définie), et je ne mets pas le extern "C"..., il me remet aussi l'erreur LNK2001.
Le problème, c'est que j'ai bosoin de la struct MaStruct, et donc je peux pas mettre extern "C" __declspec(dllimport) void MaFonction(MaStructure) avant la déclaration des fichiers .h, sinon il ne reconnapit pas MaStructure....
Bref, je suis perdu, si quelqu'un a déjà eu un problème comme ça, pensez à un pauvre débutant en informatique

Rabbi Jakob
Afficher la suite 

Votre réponse

8 réponses

Meilleure réponse
Rabbi Jakob 4 Messages postés vendredi 3 août 2007Date d'inscription 7 août 2007 Dernière intervention - 7 août 2007 à 14:27
1
Merci
j'ai finalement pu trouver ce qui n'allait pas.
Il y avait dans un fichier en-tête appelé par MaLib.h un #define _FSSAPI_decl  __declspec(dllimport) et je l'ai remplacé par _FSSAPI_decl extern"C"__declspec(dllimport)
C'était donc une erreur dans la dl qui m'a été fournie apparemmenr(je dis apparemment, car j'ai juste fait un essai avec 2 fonctions, j'espère que je ne me suis pas trompé).
Merci à SAKingdom pour son attention, bonne journée à tous!!
Peace and tranquillity on earth

PS: Au fait, désolé pour les changements de taille de police dans le poste d'avant, mais je sais pas comment faire un édit pour modifier tout ça.

Merci Rabbi Jakob 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 119 internautes ce mois-ci

Commenter la réponse de Rabbi Jakob
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 6 août 2007 à 17:21
0
Merci
Les prototypes de tes fonctions sont déjà dans le .h ?
Si oui, à quoi ça sert de redéclarer le prototype. La fonction devrait être utilisable dès que tu inclus ton .h.

C++ (@++)<!--
Commenter la réponse de SAKingdom
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 6 août 2007 à 17:23
0
Merci
Ah oups

"Seulement, si je ne place pas le extern "C" declspec(dllimport)...
, et que je mets seulement le fichier .h, il me lance une erreur
LNK2001, il ne trouve pas la fonction (unresolved external symbol)"

J'avais mal interprété ça.
Désolé.

C++ (@++)<!--
Commenter la réponse de SAKingdom
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 6 août 2007 à 17:28
0
Merci
Bon alors.
Dans ton .h, as tu ajouté ceci en début de fichier

#ifdef __cplusplus
extern "C" {
#endif

et ceci en fin

#ifdef __cplusplus
}
#endif

En gros, ça devrait donner ça

//.h
#ifndef _MADLL_INCL
#define _MADLL_INCL

#ifdef __cplusplus

extern "C" {

#endif

int __stdcall MaFonction1  (void);
int __stdcall MaFonction2 (int);

#ifdef __cplusplus
}
#endif

#endif

C++ (@++)<!--
Commenter la réponse de SAKingdom
Rabbi Jakob 4 Messages postés vendredi 3 août 2007Date d'inscription 7 août 2007 Dernière intervention - 6 août 2007 à 18:04
0
Merci
Oui, j'ai exactement le schéma que tu m'as dit; a priori, je pense que le fichier .h qui m'a été donné est bon, puisque ce n'est pas moi qui l'ai fait lol. Ce que je trouve étrange,  c'est que si je ne mets pas le extern "C"declspec(dllimport) FonctionSimple(double, double), que je mette juste le header MaDll.h, et que  j'appelle FonctionSimple(1.2), il me sort que FonctionSimple ne fonctionne pas avec un seul double. En revanche, si je mets FonctionSimple(1.2,5..3), là il me met l'erreur LNK2001 comme quoi il ne connaît pas la fonction. De plus, quand je tape FonctionSimple( Visual Studio me met qu'il faut que je rentre 2 doubles. C'est signe qu'il connaît déjà le prototype de la fonction, non? Donc a priori, je ne devrai avoir besoin de réécrire le prototype en début de programme, normalement?
Commenter la réponse de Rabbi Jakob
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 6 août 2007 à 18:52
0
Merci
Les prototypes sont bien déclarés dans le .h. Inutile d'en ajouter.
L'erreur survient lors du linkage. Le linker ne trouve pas la fonction dans les lib que tu lui donne.
Soit la lib n'est pas correcte (ce qui m'étonnerais), soit tu as fais une erreur quand tu l'as ajouté.

Essais d'ajouter ceci dans le code
#pragma comment(lib, "malib.lib")

Exemple:

#include <windows.h>
#include "malib.h"

#pragma comment(lib, "malib.lib")

C++ (@++)<!--
Commenter la réponse de SAKingdom
Rabbi Jakob 4 Messages postés vendredi 3 août 2007Date d'inscription 7 août 2007 Dernière intervention - 7 août 2007 à 10:07
0
Merci
J'ai essayé ton code, et il me sort cette fois-ci l'erreur LNK2019. J'ai regardé si ça pouvait être dû à une erreur dans la convention d'appel (std_call,...) .J'ai regardé mon fichier .h, parce que le schéma de mon header MaLib.h n'est pas exactement comme celui que tu m'as précisé, les prototypes de mes fonctions se présentent comme ça: _FSSAPI_decl
double FonctionSimple(
double,
double); , il n'y a pas le __stdcall dont tu parlais tout à l'heure. En revanche, dans l'output de mon debugger,, il me marque unresolved external symbol"__declspec(dllimport) double __cdecl FonctionSimple(double, double)". Je pense que c'est parce que les fonctions ne sont pas définies dans une classe. Je ne sais pas si dans ce cas il faut faire une procédure d'appel spécial, ce que m'étonnerait puisque la procédure d'appel __cdecl à l'air d'être la procédure d'appel par défaut.

Je viens aussi d'essayer le #pragma (linker,"/DEFAULTLIB:MaLib.lib"), parce que windows.h redéfinit le type BOOLEAN qui est déjà défini dans MaDll.h (sous winnt.h, BOOLEAN est un BYTE, sous MaLib.h, c'est un char), mais ça n'a pas avancé le problème apparemment.

J'ai aussi essayé d'enlever le header windows.h, pour éviter les rédéfinitions, et là il me ressort l'erreur LNK2019, et de même si je mets le #pragma comment(lib, "MaLib.lib") et que j'enlève MaLib.lib des additional dependencies de mon projet afin d'éviter une éventuelle redéfinition.
En revanche, je ne vois pas trop à quoi cela sert d'ajouter le header windows.h à mon projet. Il est nécessaire à l'appel d'une dll externe?

J'ai enfin essayé une autre solution: comme ma dll a été écrit en C et que je code en C++, j'ai essayé de mettre un extern "C" (sans __declspec(dllimport)) devant le prototype de la fonction, mais là encore sans succès (C2732, redéfinition des fonctions). Je vais regarder en mode verbeux si j'obtiens quelquechose de plus consistant....
Commenter la réponse de Rabbi Jakob
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 7 août 2007 à 13:50
0
Merci
Salut,

Si tu galère trops et que tu veux plus une solution qui marche que la "bonne" solution, tu peux utiliser LoadLibrary/GetpProcAdress.

Il y a un exemple (Sous un exemple de dllimport) ici.
Commenter la réponse de cs_rt15

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.