Ok, mais quand on crée un projet C++ avec Visual 8, il y a la possiblité de faire un projet avec en-tête précompilé sans MFC. Concrêtement, ça se passe comment dans ce cas là? :koi:
Version imprimable
Ok, mais quand on crée un projet C++ avec Visual 8, il y a la possiblité de faire un projet avec en-tête précompilé sans MFC. Concrêtement, ça se passe comment dans ce cas là? :koi:
L'étape obligatoire, c'est de désactiver les en-têtes précompilés dans les fichiers source C, et de ne les utiliser qu'en C++ (ou inversement).
Ensuite, quand on n'utilise pas MFC, on est généralement libre d'utiliser ou non stdafx.h, puisque la plupart des headers C++ sont sautés silencieusement.
Ou bien, on peut aussi mettre des #ifdef __cplusplus dans stdafx.h et l'inclure partout...
Note: Contrairement à Visual 6, Visual 8 offre la possibilité d'utiliser deux PCH différents. On peut donc en générer un pour les fichiers source C et un pour les fichiers source C++, il suffit de ne pas leur donner le même nom.
OK ça devient rudement compliqué. Je vais m'arrêter là pour les questions car je pollue le post de notre collègue. Je lancerai un nouveau post si besoin plus tard!
A+
Wow ça participe dur les gars !!
Bon j'ai tous repris de zéro !!! Et j'intègre les choses une à une !
Alors Etape 1 : je reprends le squelette vierge de l'application C++ (avec des MFC) qui permet de générer la DLL. Seuls les corps de méthodes sont à coder (par défaut, les méthodes retournent -1
Etape 1 OK : la DLL se construit.
Etape 2 : J'intègre dans le fichier .cpp où il faut coder le corps des méthodes les entete .h de librairie C à utiliser avec en plus dans un coprs un simple appel à une méthode au pif de chacune de ces librairies :
Etape 2 OK : la DLL se construit. Seul petit hic, CURL me cause 2 warning :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <curl/curlver.h> #include <curl/curl.h> #include <curl/stdcheaders.h> #include <curl/types.h> #include <curl/mprintf.h> #include <curl/multi.h> #include <curl/easy.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/pkcs12.h> #include <libxml/tree.h> #include <libxml/parser.h> #include <libxml/xpath.h> #include <libxml/xpathInternals.h> #include <libxml/xmlschemas.h>
Je ne comprends pas c'est warning mais baste, la DLL se créee.Citation:
Compiling...
TiersdeConfiance.cpp
TiersdeConfianceAuto.cpp
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(28) : warning C4273: 'fread' : inconsistent dll linkage. dllexport assumed.
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(29) : warning C4273: 'fwrite' : inconsistent dll linkage. dllexport assumed.
Generating Code...
Linking...
Creating library Release/TiersdeConfiance.lib and object Release/TiersdeConfiance.exp
TiersdeConfiance.dll - 0 error(s), 2 warning(s)
Etape 3 : Et c'est là qu'arrive le 1er problème :
Je crée un fichier Util.cpp et Util.h que j'intègre au projet :
Alors simplifier et bien bien faire apparaitre le bug :
Util.cpp : fichier vide
Util.h : fichier vide
Je compile et j'ai l'erreur :
C'est quoi c Windows erreur ?Citation:
--------------------Configuration: TiersdeConfiance - Win32 Release--------------------
Compiling...
Util.cpp
D:\prog\vc++6\TiersConfianceDebug\Util.cpp(2) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Error executing cl.exe.
TiersdeConfiance.dll - 1 error(s), 0 warning(s)
Etape 3 OK : j'ai utilisé le wizard pour crée ma classe C++. Le code de util.cpp devient
et util.h :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 // Util.cpp: implementation of the Util class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "TiersdeConfiance.h" #include "Util.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Util::Util() { } Util::~Util() { } /////////////////////////////////////////////////////////////////////////////// void Util::BSTRtoASC (BSTR str, char * &strRet) { if ( str != NULL ) { unsigned long length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str), NULL, 0, NULL, NULL); strRet = new char[length]; length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str), reinterpret_cast <char *>(strRet), length, NULL, NULL); strRet[length] = '\0'; } } /////////////////////////////////////////////////////////////////////////////// void Util::ASCtoBSTR (char * str, BSTR * strRet) { if ( str != NULL ) { unsigned long length = strlen(str); int ResultLength = MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, reinterpret_cast <char *>(str),length,NULL,0); *strRet = SysAllocStringLen( NULL, ResultLength); MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, reinterpret_cast <char *>(str),length,*strRet,ResultLength); } }
Etape 4 : J'inclue mon propre code C (fichiers .c et .h indépendants)...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 // Util.h: interface for the Util class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_UTIL_H__52FCB4C3_A262_4B91_96D1_CA981F11A581__INCLUDED_) #define AFX_UTIL_H__52FCB4C3_A262_4B91_96D1_CA981F11A581__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class Util { public: Util(); virtual ~Util(); void BSTRtoASC (BSTR str, char * &strRet); void ASCtoBSTR (char * str, BSTR * strRet); }; #endif // !defined(AFX_UTIL_H__52FCB4C3_A262_4B91_96D1_CA981F11A581__INCLUDED_)
Etape 4 : Problème idem etape 3 :
J'utilise le class wizard mais comme c du code C, il refuse d'utiliser l'extension .c au fichier. Comment réparer ce fichier à la main pour que ca compile ?Citation:
--------------------Configuration: TiersdeConfiance - Win32 Release--------------------
Compiling...
Constant.c
D:\prog\vc++6\TiersConfianceDebug\Constant.c(51) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Error executing cl.exe.
TiersdeConfiance.dll - 1 error(s), 0 warning(s)
Etape 4 OK : j'ai viré l'option des entetes precompilées. Je ne sais pas à quoi ca sert ou si c plus performant pour le programme mais j'ai coché "no use precompiled header file". Et la DLL se génère.
Etape 5 : j'intègre le code existant (dont je générais un .lib auparavant) avec les fichiers .c et .h
Etape 5 : Erreur. J'inclus le header/source suivant :
J'obtiens l'erreur :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifndef _INCLUDE_TEDETIS_E_SSL_SESSION_H #define _INCLUDE_TEDETIS_E_SSL_SESSION_H #include "tedetisTypes.h" #include "tedetisError.h" #include "tedetisUtils.h" typedef struct SSLSessionInfo{ char *url; X509 *cert; char *pass; char *servcert; char *servcertDN; EVP_PKEY *pkey; }SSLSessionInfo; STATUS TEDETIS_E_openSSLSession(CertInfo *desiredCert, char* appName, SSLSessionInfo** sslSessionHandle, char *certdir); STATUS TEDETIS_E_closeSSLSession(SSLSessionInfo* sslSessionHandle); STATUS TEDETIS_E_enumCertificateInStore(char * appName, CertInfo** certInfo, int* certNumber, char *certdir); #endif /*_INCLUDE_TEDETIS_E_SSL_SESSION_H */
Et là je ne comprends plus trop .... une idée ? :?Citation:
--------------------Configuration: TiersdeConfiance - Win32 Release--------------------
Compiling...
TiersdeConfianceAuto.cpp
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(28) : warning C4273: 'fread' : inconsistent dll linkage. dllexport assumed.
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(29) : warning C4273: 'fwrite' : inconsistent dll linkage. dllexport assumed.
Linking...
mfcs42.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in MSVCRT.lib(dllmain.obj)
mfcs42.lib(dllmodul.obj) : warning LNK4006: _DllMain@12 already defined in MSVCRT.lib(dllmain.obj); second definition ignored
Creating library Release/TiersdeConfiance.lib and object Release/TiersdeConfiance.exp
Release/TiersdeConfiance.dll : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
TiersdeConfiance.dll - 2 error(s), 3 warning(s)
RQ : Les headers intégrés en haut du fichier :
n'ont pas encore été ajoutés au projet. Cependant, le message d'erreur n'y fait pas allusion (l'erreur affichée étant prioritaire sur les #include je suppose)Code:
1
2
3 #include "tedetisTypes.h" #include "tedetisError.h" #include "tedetisUtils.h"
Ta DLL MFC n'est peut-être pas du bon type : Une DLL d'extension MFC peut posséder un DllMain(), mais une "MFC Regular DLL" (DLL normale utilisant MFC) ne doit pas avoir de DllMain(), et posséder à la place un objet d'une classe dérivée de CWinApp.
PS: Ta classe CUtil, je la rendrait non-instanciable à ta place, si elle ne contient que des méthodes statiques.
Genre, déclarer un constructeur par défaut privé, et ne pas le définir...
classe non instanciable ?
faut rajouter statique devant les prototypes et virer le constructeur ? (désolé je viens du monde java)
Et que proposes-tu ?Citation:
Ta DLL MFC n'est peut-être pas du bon type : Une DLL d'extension MFC peut posséder un DllMain(), mais une "MFC Regular DLL" (DLL normale utilisant MFC) ne doit pas avoir de DllMain(), et posséder à la place un objet d'une classe dérivée de CWinApp.
Pour info, mon fichier TiersdeConfiance.h :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 // TiersdeConfiance.h : main header file for the TIERSDECONFIANCE DLL // #if !defined(AFX_TIERSDECONFIANCE_H__2B8205FC_398C_4B1B_BD99_B53C3330C2EA__INCLUDED_) #define AFX_TIERSDECONFIANCE_H__2B8205FC_398C_4B1B_BD99_B53C3330C2EA__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h" // main symbols ///////////////////////////////////////////////////////////////////////////// // CTiersdeConfianceApp // See TiersdeConfiance.cpp for the implementation of this class // class CTiersdeConfianceApp : public CWinApp { public: CTiersdeConfianceApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTiersdeConfianceApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL //{{AFX_MSG(CTiersdeConfianceApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_TIERSDECONFIANCE_H__2B8205FC_398C_4B1B_BD99_B53C3330C2EA__INCLUDED_)
<FAUX>Eh bien, si c'est la CWinApp de ta DLL, tu dois la mettre dans ton projet, et virer ta DllMain().</FAUX>
Edit: Mince, y'a un truc pas normal : Il ne devrait pas y avoir de DllMain() dans MSVCRT.lib... Qu'est-ce que c'est que cette histoire ?
Hum... si le "s" de "mfcs42.lib" signifie statique, c'est qu'il y a un conflit entre MFC et la CRT: Les deux doivent être statiques ou les deux doivent être en DLL.
Etape 5 OK : j'ai ajouté mfcs42.lib dans les link.
Etape6 : je crée des appels pour tester l'importation des .h et .c. J'ai un problème :
Je vais ajouter les "ifdef c++ extern "C".... "Citation:
--------------------Configuration: TiersdeConfiance - Win32 Release--------------------
Compiling...
TiersdeConfianceAuto.cpp
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(28) : warning C4273: 'fread' : inconsistent dll linkage. dllexport assumed.
C:\TEDETIS\LIBCURL-7.15.1-MSVC-WIN32-SSL-0.9.8A-ZLIB-1.2.3\INCLUDE\curl/stdcheaders.h(29) : warning C4273: 'fwrite' : inconsistent dll linkage. dllexport assumed.
Linking...
Creating library Release/TiersdeConfiance.lib and object Release/TiersdeConfiance.exp
TiersdeConfianceAuto.obj : error LNK2001: unresolved external symbol "void __cdecl log_append(int)" (?log_append@@YAXH@Z)
Release/TiersdeConfiance.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
TiersdeConfiance.dll - 2 error(s), 2 warning(s)
sisi ça marche :D (grâce à google)
Je continue avec les "extern C" et appremment pour à l'air de compiler ET surtout de Linker pour avoir une DLL.
Une question annexe : comment fait-on pour tester un programme DLL ? Vu qu'il n'y a pas de main et que si j'en mets un, ça plante :/.
Tu fais un programme qui utilise la DLL.
Etape 6 OK : J'ai réussi à tout intégrer le code et je génère la DLL.
Etape 7 : Je lance le programme .exe qui teste la DLL (les fonctions accessibles où je devais rajouter du code). J'obtiens l'erreur "Impossible de se connecter à la DLL". Je crée donc en vitesse un nouveau projet VC++ (Win32 console application) j'inclus TOUTES les sources servant à construire la DLL. Je compile, link et tous marche, le .exe s'est généré.
Je lance le .exe, lequel fais appel à la méthode main() dans laquelle je fais appel à une fonction d'export de la DLL.
La console s'affiche, à l'appel de la méthode "DLL" j'obtiens l'erreur :
"libeay32.dll introuvable". Il s'agit d'une librairie d'openSSL.
Je courre dans le package binaries d'OpenSSL, meme version que celle de la lib que j'utilise dans le programme. Je chope la DLL "libeay32.dll" illico presto, je réexécute le programme.
J'obtiens l'erreur :
Morale : j'ai pas la bonne DLL pourtant venant des binaries d'openSSL et est LA MEME VERSION que la librairie que j'inclus dans le projet !Citation:
"L'ordinal 2821 est introuvable dans la bibliothèque de liaisons dynamique LIBEAY32.dll"
Mon dieu, je n'arrive toujours pas à executer mon programme, que faire ? faut-il essaié les 36000 version de la DLL en question existante ?
Merci.
Désolé, là je capitule.
Je ne vois absolument pas ce qui peut générer une telle erreur.
Et ce n'est pas tout !! :D.
Bon je suis arrivé à corriger l'erreur. J'ai installé la dernière version d'OpenSSL :
Win32OpenSSL_Light-0_9_8e.exe
Je l'install, il me met dans c:\windows\system32 les librairies libeay32.dll et libssl.dll ... je vire donc la dll à côté de mon exe de test pour que celles ci dans c:\windows\system32 soient prises en compte.
Je relance le programme de test. J'ai l'erreur :
"zlib1.dll introuvable".
Je rajoute cette dll à côté de l'exe de test et j'obtiens l'erreur
"ordinal 1364 ...blabla...libeay32.dll" ... je commence à en avoir raz la casquette de ce trio C/C++/Windows ! :evilred:
Ce n'est pas le "trio C/C++/Windows" qui pose problème, mais le quintor "C/C++/Windows/MFC/Bibliothèques tierces".
Oui plutôt. Mais mon boss commence à en avoir raz le bol, et tout seul sans expert VC++, c'est pas facile. Encore un projet info qui tombe à l'eau (c'était chiffré à 5 jours, je devais livrer en début de semaine). Sans parler que je n'ai même pas pu faire les tests. Mon boss a fini par laisser tomber les "alors s'en est où ?", jlui répond en chinois à chaque fois en disant "J'ai un problème d'ordinal dans une DLL annexe". Du coup, il n'ose plus rien demander :yaisse2: