J'essaye de remplacer les fonctions C standard par ma propre implémentation.

void* malloc(size_t size) {}
void free(void*) {}

Me donne les avertissements / erreurs suivants:

1>main.cpp(26): warning C4273: 'malloc': inconsistent dll linkage
1>  C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_malloc.h(97): note: see previous definition of 'malloc'
1>main.cpp(31): warning C4273: 'free': inconsistent dll linkage
1>  C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_malloc.h(85): note: see previous definition of 'free'
1>ucrtd.lib(ucrtbased.dll) : error LNK2005: _free already defined in main.obj
1>ucrtd.lib(ucrtbased.dll) : error LNK2005: _malloc already defined in main.obj
1>     Creating library ..\bin\\app.lib and object ..\bin\\app.exp
1>..\bin\\app.exe : fatal error LNK1169: one or more multiply defined symbols found

Existe-t-il un moyen de remplacer la fonction malloc / free dans Visual C ++ 2015 sans utiliser #define? (J'utilise des bibliothèques tierces et je ne souhaite pas modifier leur code).

1
Alexander Dyagilev 21 avril 2017 à 17:53

3 réponses

Meilleure réponse

Oui, c'est possible. La façon dont cela fonctionnera est que votre code doit accrocher malloc () et free () dans msvcrt.dll avant que tout code ait la possibilité d'appeler ces fonctions. Je pense que vous devriez pouvoir utiliser Microsoft Detours pour accrocher ces fonctions. Vous voudrez peut-être aussi accrocher HeapAlloc () et HeapFree () dans kernel32.dll à la place, car ils appelleront éventuellement cette API.

3
Man Vs Code 25 avril 2017 à 14:58

Vous ne pouvez pas remplacer ces fonctions même si vous configurez /FORCE:MULTIPLE dans l'éditeur de liens car il utilisera le premier objet trouvé. Et ce sera la mise en œuvre de CRT. Voulez-vous vraiment remplacer cette fonction? Si la réponse est «oui», vous ne devriez utiliser aucune fonction de bibliothèque d'exécution C du tout - et il y aura plus de douleur (sprintf(), strlen() et autre fonction de chaîne, fopen() utilise également CRT). Vous devez également configurer votre projet d'abandonner CRT. Pensez encore.

0
Prime Ape 25 avril 2017 à 11:41

En supposant que vous souhaitiez déboguer un problème de mémoire dans une bibliothèque tierce, fournir votre propre implémentation de free () et malloc () et la lier à votre bibliothèque tierce ne fonctionnera pas.

Comme le signale l'éditeur de liens dans le message d'erreur, vous avez deux implémentations de la même fonction. Un dans vos fichiers (app.lib), et un autre dans ucrtd.dll qui s'appelle Common Runtime Library et où sont fournis malloc () et free ().

Si vous supprimez ucrtd.dll de votre projet, vous supprimerez également de nombreuses autres fonctions nécessaires à votre application. Ce n'est donc probablement pas une option.

Comme Ben l'a mentionné, s'il s'agit de déboguer des problèmes de mémoire, vous pouvez utiliser l'API CRT Debug Heap, qui sont des outils intégrés que vous activez en définissant des symboles (au moment de la compilation) et des fonctions supplémentaires (voir la documentation). Néanmoins, vous pouvez accrocher le processus d'allocation de mémoire, mais sans aller jusque-là, vous pouvez afficher et vérifier beaucoup de choses au début.

Ceci est bien sûr plus ou moins facile à faire selon que vous pouvez accéder au code source de la bibliothèque que vous souhaitez déboguer, ce que nous ne connaissons pas. Si vous n'avez pas accès au code source, d'autres outils peuvent être nécessaires.

Mettre à jour: Selon que vous pouvez accéder à la source de la bibliothèque que vous souhaitez déboguer, vous pourriez être intéressé par l'une des trois méthodes citées dans cette question: Emballage de la fonction dans le même fichier

1
Community 23 mai 2017 à 12:10