J'essaie de créer une bibliothèque statique à partir d'une classe, mais lorsque j'essaie de l'utiliser, j'obtiens toujours des erreurs avec des références non définies sur quoi que ce soit. La façon dont j'ai procédé était de créer le fichier objet comme
g++ -c myClass.cpp -o myClass.o
puis l'emballer avec
ar rcs myClass.lib myClass.o
Il y a quelque chose qui me manque évidemment de façon générale. Je parie que c'est quelque chose avec des symboles. Merci pour tout conseil, je sais que c'est probablement quelque chose que je pourrais découvrir si je lis un tutoriel, donc désolé si vous vous embêtez à nouveau avec des trucs stupides :)
myClass.h:
class myClass{
public:
myClass();
void function();
};
myClass.cpp:
#include "myClass.h"
myClass::myClass(){}
void myClass::function(){}
programme utilisant la classe:
#include "myClass.h"
int main(){
myClass mc;
mc.function();
return 0;
}
enfin je le compile comme ceci:
g++ -o main.exe -L. -l myClass main.cpp
l'erreur est juste classique:
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined
reference to `myClass::myClass()'
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined
reference to `myClass::function()'
collect2: ld returned 1 exit status
C'est probablement un problème d'ordre des liens. Lorsque l'éditeur de liens GNU voit une bibliothèque, il supprime tous les symboles dont il n'a pas besoin. Dans ce cas, votre bibliothèque apparaît avant votre fichier .cpp, donc la bibliothèque est supprimée avant le. Le fichier cpp est compilé. Procédez comme suit:
g++ -o main.exe main.cpp -L. -lmylib
ou
g++ -o main.exe main.cpp myClass.lib
L'éditeur de liens Microsoft ne prend pas en compte l'ordre des bibliothèques sur la ligne de commande.
Une autre cause possible: oublier extern "C"
.
J'ai rencontré cela parce que j'essayais de lier un programme C++ avec une bibliothèque statique C. L'en-tête de la bibliothèque n'avait pas extern "C"
donc l'éditeur de liens recherchait un nom de fonction altéré, et la bibliothèque avait en fait le nom de fonction non mélangé.
Il a fallu un certain temps pour comprendre ce qui se passait, alors j'espère que cela aide quelqu'un d'autre.
C'est un problème de savoir comment l'éditeur de liens optimise le code de sortie. Supposons que nous ayons un exécutable qui utilise deux bibliothèques: Lib_A et Lib_B. Lib_A dépend de Lib_B Le Lib_A définit les symboles: Lib_A1 et Lib_A2 , et le Lib_B définit le symbole Lib_B1 et Lib_B2 . Supposons maintenant que l'exécutable utilise uniquement le symbole Lib_A1 , et Lib_A1 utilise symbole Lib_B1 qui est défini dans Lib_B. Le symbole Lib_B1 n'est jamais utilisé dans l'exécutable.
g++ .... -lLib_B -lLib_A
L'éditeur de liens fonctionne comme ceci: j'ai un exécutable qui lie d'abord Lib_B. Je ne vois pas que l'exécutable utilise le symbole Lib_B1 ni Lib_B2 . Ils ne sont pas nécessaires, je vais donc les définir. Plus tard, l'éditeur de liens voir. Oh, j'ai une autre bibliothèque Lib_A. Je peux voir que l'exécutable utilise le symbole Lib_B1 . Je vais le conserver et définir le symbole inutilisé Lib_B2 . Il ne voit pas que Lib_B1 utilise Lib_A1 , qui est déjà indéfini.g++ ... -lLib_A -lLib_B
L'éditeur de liens fonctionne comme ceci: j'ai un exécutable qui lie d'abord Lib_A. Oh, je peux voir que l'exécutable utilise Lib_A1 . Je vais les conserver et les définir Lib_A2 . Plus tard, il peut voir. Oh, j'ai une autre bibliothèque Lib_B. Je peux voir que maintenant exécutable avec des symboles déjà liés, utilise Lib_B1 , je vais les garder. En conséquence, il conserve Lib_B1 et Lib_A1 , et indéfini Lib_B2 et Lib_A2 .Utilisation:
g++ -o main.exe main.cpp myClass.lib
L'utilisation du chemin d'accès à la bibliothèque et de l'option -l est lourde de problèmes, mais si vous devez le faire, renommez votre bibliothèque en libmylib.a, puis compilez comme:
g++ -o main.exe main.cpp -L. -lmylib
Notez également que pour des raisons de portabilité, c'est généralement une mauvaise idée d'utiliser la casse mixte dans les noms des fichiers source ou de sortie.
Cela devrait éviter les erreurs de liaison et créer la bibliothèque partagée .so:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true