Comment avez-vous correctement lien vers une bibliothèque statique à l'aide de g++
Solution:
Merci à tous ceux qui ont formulé des observations sur cette question, mais j'ai résolu sur un autre forum, et pensé que je devrais poster la réponse ici pour quelqu'un ayant le même problème.Donc, je crois que seuls les bibliothèques dynamiques de faire usage de __declspec(dllexport), de sorte que lorsque vous essayez de créer une bibliothèque statique, les méthodes sont exportés (les noms doivent être déformés pour être en c++ compatible), de sorte que lors de la déclaration extern "C" __declspec.... vous vous retrouvez avec des noms de méthodes qui ne sont pas reconnus lorsque vous essayez de lier statiquement.
Donc, la solution simple.....supprimer l' __declspec
J'ai 2 projets, l'un est une bibliothèque statique, l'autre est juste une application win32.
Je veux simplement inclure la bibliothèque, j'ai créé dans mon application win32, cependant g++ garde me donne cette erreur:
../MyLib/TestClass.h:16: undefined reference to `imp__ZTV9TestClass'
C'est l'erreur que je reçois lorsque vous essayez de compiler l'application, même si ce fichier fait partie de la bibliothèque.
J'ai tenté de créer le plus de la version simplifiée de ce projet que possible pour essayer de trouver l'erreur.
Voici les fichiers source pour les deux projets:
MyLib.h - C'est le principal fichier include pour les clients de référence des fonctions de la bibliothèque
#ifndef MYLIB_H
#define MYLIB_H
#include "libexport.h"
#include "TestClass.h"
#endif /* MYLIB_H */
libexport.h - Assez de fichier générique pour définir importer/exporter des mots-clés
#ifndef LIBEXPORT_H
#define LIBEXPORT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LIB
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
}
#endif
#endif /* LIBEXPORT_H */
TestClass.h
#ifndef TESTCLASS_H
#define TESTCLASS_H
#include "libexport.h"
class DLL_EXPORT TestClass
{
public:
TestClass() {};
virtual ~TestClass() {};
void TestFunc();
};
#endif /* TESTCLASS_H */
TestClass.cpp
#define LIB
#include <stdio.h>
#include "TestClass.h"
void TestClass::TestFunc()
{
printf("This function was called from within the library.\n");
}
Et enfin, l'application win32 qui implémente la bibliothèque:
Main.cpp
#include <windows.h>
#include "../MyLib/MyLib.h"
#pragma comment(lib, "libmylib.a")
int __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
TestClass *myClass = new TestClass();
delete myClass;
myClass = 0;
return 0;
}
La bibliothèque se compile sans erreur, cependant, c'est la sortie lors de la compilation de l'application principale:
g++.exe -c -g -MMD -MP -MF build/Debug/MinGW-Windows/main.o.d -o build/Debug/MinGW-Windows/main.o main.cpp
mkdir -p dist/Debug/MinGW-Windows
g++.exe -mwindows -o dist/Debug/MinGW-Windows/testclient build/Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib
build/Debug/MinGW-Windows/main.o: In function `TestClass':
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to `_imp___ZTV9TestClass'
make[2]: Leaving directory `/c/Users/Nick/Documents/NetBeansProjects/TestClient'
build/Debug/MinGW-Windows/main.o: In function `~TestClass':
make[1]: Leaving directory `/c/Users/Nick/Documents/NetBeansProjects/TestClient'
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:17: undefined reference to `_imp___ZTV9TestClass'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGW-Windows/testclient.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
La plupart des autres postes que j'ai vu à ce sujet, dire que le problème réside dans le lien entre l'ordre, mais même après l'ajout d'-lmylib au début du compilateur construire la ligne, les mêmes erreurs persistent:
g++.exe -lmylib -mwindows -o dist/Debug/MinGW-Windows/testclient build/Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib
build/Debug/MinGW-Windows/main.o: In function `TestClass':
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to `_imp___ZTV9TestClass'
J'ai vraiment besoin d'aide sur ce, j'ai construit beaucoup de bibliothèques dynamiques avant d'utiliser le code ci-dessus, et il fonctionne sans problème, je ne comprends pas pourquoi j'ai tant de peine à construire une simple bibliothèque statique. Toute aide est grandement appréciée.
libmylib.a
(sans -l
) au lieu de -lmylib
. Vous pourriez avoir à spécifier le chemin d'accès complet: build/Debug/libmylib.a
ou quoi que ce soit.Il ressemble à celui que produit la même chose: g++.exe -mwindows ../MyLib/dist/Debug/MinGW-Windows/libmylib.a-o dist/Debug/MinGW-Windows/testclient build/Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib make[2]: Quittant le répertoire
/c/Users/Nick/Documents/NetBeansProjects/TestClient' make[1]: Leaving directory
/c/Users/Pseudo/Documents/NetBeansProjects/TestClient " build/Debug/MinGW-Windows/main.o: Dans la fonction TestClass': C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to
_imp___ZTV9TestClass'l'ordre de la liaison d'objets et ar archives est trop important
la nsa, c'EST à la fin, j'ai simplement dit que je l'ai essayé au début avec aucun résultat, il aide si vous regardez les informations fournies.
Mettre
../MyLib/dist/Debug/MinGW-Windows/libmylib.a
après build/Debug/MinGW-Windows/main.o.
OriginalL'auteur DivXZero | 2012-01-31
Vous devez vous connecter pour publier un commentaire.
-L/path/to/library/
et-lName
que g++ options a fonctionné pour moi. Ne spécifiez pas le nom de la bibliothèque dans lepath/to/library
.Oh, désolé, doit l'avoir manquée. Est
mylib
nommélibmylib.a
? Parce que c'est ce que l'option-l suppose qu'il est.OriginalL'auteur TeaOverflow
Essayez de placer -L et-L avant de la main.o dans la liaison de la ligne de commande.
OriginalL'auteur selalerer
Solution: Merci à tous ceux qui ont formulé des observations sur cette question, mais j'ai résolu sur un autre forum, et compris je poste la réponse ici pour quelqu'un ayant le même problème.
Donc, je crois que seuls les bibliothèques dynamiques de faire usage de
__declspec(dllexport)
, de sorte que lorsque vous essayez de créer une bibliothèque statique, les méthodes sont exportés (les noms doivent être déformés pour être en C++ compatible), de sorte que lors de la déclaration deextern "C" __declspec....
vous vous retrouvez avec des noms de méthodes qui ne sont pas reconnus lorsque vous essayez de lier statiquement.Alors, simple correctif: retirer le
__declspec
OriginalL'auteur