cool… :aie:
Version imprimable
cool… :aie:
VDM :(
J'apprends le métier de développeur :aie:
Alors que mon domaine est le hard...
En effet c'est très moche....
Mais le résultat m'intéresse tout de même ! :)
Bon courage pour la suite !
Je posterai lorsque j'aurais réussi à compiler ;)
Je poste mais je n'arrive toujours pas à compiler :aie:
Je n'ai plus d'idée pour le forcer à compiler là, il me nargue en affichant toujours le même message:
J'ai été dans propriétés -> Editeur de lien-> Général -> Répertoires des bibliothèques supplémentaires, rien ne change...Citation:
------ Début de la génération*: Projet*: DriverBis, Configuration*: Release Win32 ------
LINK : fatal error LNK1181: impossible d'ouvrir le fichier en entrée 'usb.lib'
========== Génération*: 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
J'ai fait propriétés -> Editeur de lien -> entrée -> dépendances supplémentaires, là encore ça ne change rien...
Dans la ligne de commande, j'ai essayé /FORCE usb.lib, toujours rien!
J'ai essayé /LIBPATH usb.lib aussi, comme dit ici...
....je vous laisse deviner le résultat...
Et tout les fichiers sont correctement placés dans leur dossier et tout....
Tu as regardé ce que dit MSDN??
J'avais trouvé l'équivalent en anglais ;) ...à part pour les espaces, mais c'est une chose à laquelle je fais gaffe.
Comme les corrections classiques ont été proposées, je ne vois pas que dire de plus
Dans le doute que ça puisse être un bug de Visual, j'ai tenté ce matin de faire un nouveau projet mais je me retrouve avec le même soucis.
Je suis sûr que c'est une configuration de Visual à modifier au moins.
Après moult bricolages, des crampes aux doigts et les yeux tout rouge, je crois que j'ai viré la dernière erreur.... (me demandez pas comment j'ai fait, je cherche encore... :mrgreen:)
...mais elle a laissé place à d'autres! :aie: (dans le même genre qu'avant)
Je mets le rapport complet.... (ouch, du lourd!!!)
Code:
Je vois deux classes d'erreurs: Des définitions multiples (compilerais-tu des fichiers sources qui s'incluent les uns les autres, ou quoi?) et des fonctions dllimport non trouvées (apparemment tu oublies de lier à NTOSKrnl.lib)
Il y a aussi LINK : warning LNK4031: aucun sous-système spécifié*; CONSOLE pris par défaut à voir; tu es censé lui dire sur quel sous-système tu travailles, même si c'est "aucun" (driver).
les causes probables d'une définition multiples sont:
- Présence d'une définition non inline dans un en-tête (inclus plusieurs fois). solution? rejeter la définition dans un fichier d'implémentation (.c) ou inline-er
- Inclusions du même fichier d'objet compilé (.o) dans l'édition de lien. solution? ne pas le faire, en nettoyant le fichier de projet
C'est vrai que j'ai pas pensé à vérifier si des sources s'incluaient mutuellement... Ca serait bien tordu quand même! :koi:
Par contre j'ai des en-têtes qui en appellent d'autres, rien de dérangeant à cela?
Quand j'essaie d'ajouter ntoskrnl.lib, le compilateur me dit qu'il n'arrive pas à l'ouvrir.
EDIT: Quel idiot! En le plaçant dans le bon dossier, ça va déjà mieux :roll:
N'oublie pas de protéger tes headers !
fichier_1.h :
A faire dans chacun de tes .h !Code:
1
2
3
4
5
6
7
8
9
10
11
12 #ifndef FICHIER_1_H_ # define FICHIER_1_H_ # include <windows.h> # include "fichier_2.h" ... int MaFonction(int Entier); ... #endif /* !FICHIER_1_H_ */
EDIT : et il vaut mieux éviter d'inclure des .c entre eux...
Chaque .c inclue un ou des .h qui incluent eux-même des .h uniquement !
Et tous les .h sont protégés !
il faut bien comprendre que #include est une commande pour le préprocesseur.
Ca correspond plus ou moins à copier coller le contenu du fichier désigné puis de continuer à préprocesser (par la premiere ligne du fichier inclus, du coup)
Je viens de finir de le faire. La plupart l'était déjà en fait. Je m'attaque maintenant aux erreurs de link.Citation:
Envoyé par Metalman
L'erreur LNK2005 est-elle possible si on a une fonction qui est déclarée dans un .c ET dans un .h que ce même point .c appelle?
Par exemple:
Code:
1
2
3
4
5 //header1.h int MaFonction(char marchin) { //des instructions };
Apparemment j'aurais des trucs comme ça.Code:
1
2
3
4
5
6 //source.c #include header1.h int MaFonction(char machin) {//des instructions };
Dans les .h tu ne dois avoir QUE les les "signatures" de fonctions !
Et dans les .c tu les implémentes !
Et attention aussi : si tu modifies les .h et leurs ordres d'inclusion, il faut assez souvent faire un clean du projet et recompiler.
(C'est surtout que si tu modifies localement un .c, il sera automatiquement recompilé, mais pas toujours pour les .h)
Bref, la signature (dans le .h) d'une fonction c'est simplement :
Et dans le .c tu auras :Code:
1
2
3
4
5
6
7
8
9
10 #ifndef FILE_H_ # define FILE_H_ # include <windows.h> # include "file_2.h" int MaFonction(char arg); #endif /* !FILE_H_ */
Tu peux (et doit) avoir cela pour les fonctions exportables.Code:
1
2
3
4
5
6 #include "file.h" int MaFonction(char arg) { ... }
Pourquoi ?
Comme tu vas inclure les .h entre eux, les sources ayant besoin de fonctions présentes dans d'autres .c vont automatiquement comprendre qu'elles ne trouvent pas le code, mais qu'il sera mis lors de la phase de link !
C'est en rapport avec la règle de la définition unique (one definition rule ou ODR).
Pour bien comprendre, il faut comprendre la différence entre déclaration et définition.Citation:
Toute chose utilisée doit être définie une et une seule fois.
Une déclaration dit au compilateur "je sais que ceci sera défini, ne t'inquiète pas".
Une définition lui dit au contraire "Voici la définition de cette chose à utiliser pendant l'édition de lien".
Pour la compilation, et l'édition de lien, il n'y a que le concept de symbole. Un symbole à un genre parmi: type, variable, fonction, espace de nom et littéral.
Chacun à sa forme de déclaration et de définition.
En gros, les définitions ont les formes suivantes:
- struct t{/**/}; ou typedef type nom; ou encore using nom = type;
- int i;
- void f(int a){/**/}; (ici, "int a" est aussi une définition)
- namespace truc {/*contenu*/}
- 2, '2', "phrase"
Les déclarations, qui ne créent pas de symbole complet:
- struct t;, t est alors un type incomplet, utilisable en l'état uniquement pour déclarer des pointeurs ou références.
- external int i; (surtout, pas de valeur)
- void f(int a); (ici, "a" est un commentaire, et int fait parti de la déclaration de f)
- déclarer un namespace n'a pas d'intérêt, mais je crois que ca serait namespace truc;
- rien pour les littéraux.
Tu peux déclarer les choses autant de fois que tu veux, mais une seule définition est autorisée:
Code:
1
2
3
4
5
6
7
8
9 int main(); int f();//déclaration: il existe f une fonction de void vers int int f();//déclaration: il existe f une fonction de void vers int int f() {return 0;}//définition: f est {return 0;} int f();//déclaration: il existe f une fonction de void vers int int f() {return 1;}//définition: f est {return 1;} int main() { return f();//quelle définition de f le compilateur doit-il choisir? c'est ambigü, dont c'est rejeté. }
Malgré mon tout petit niveau de programmeur en C, c'est toujours ce raisonnement que je suis. Mais rentrer dans les détails ne fait pas mal et ça me permet mieux comprendre. :)
Apparemment, les programmeurs du code que j'ai récupéré ne sont pas aussi friands de ces règles de base :lol:
Bon, je retourne à mon rapport d'erreurs; c'était mes 2min de relaxation sans C (ou presque)