7
votes

Supprimer la sortie à la cout de la bibliothèque liée

Je dois relier mes programmes C ++ contre quelques bibliothèques partagées qui génèrent trop de puissance sur STD :: COUT et STD :: CERR Les deux inutiles pour mes utilisations. J'ai accès au code source C ++ de ces bibliothèques, mais je ne peux pas les modifier.

Y a-t-il un moyen de rediriger leur sortie dans un flux différent ou de le supprimer lorsqu'il est lié à mon code? Je préférerais une manière propre en C ++, mais craignant que cela soit impossible, je serai aussi content des hacks Sale Linker. Aussi un "proxy libstdc ++ " irait bien en dernier recours.

Je travaille avec une boîte à outils GNU ( g ++ , libtool , ld ) sous Linux.


4 commentaires

Ce n'est pas vraiment cerr / cout , mais des emballages autour de stdout_fileno et starr_fileno . Il n'y a rien de magique à propos de C ++, sauf qu'il a des utilisateurs.


@Matt: Je viens de mentionner que j'espère que l'on pourrait exploiter que lorsque je relie les codes C ++ (par exemple, des symboles de remplacement). Mais peut-être que cette information linguistique est partie à ce stade.


Imo pas exactement un duplicata, mais connexe: Stackoverflow .Com / Questions / 533038 / ...


@SBI: J'espérais une solution moins intrusive possible, possibles à la phase de liaison.


6 Réponses :


0
votes

S'ils sont vraiment émettant via std :: cout et std :: cerr alors vous pouvez remplacer les tampons de flux de l'objet, mais vous devriez rediriger votre propre programme sortie à travers d'autres flux. Voir Cette question pour comment faire cela.

Cependant, s'ils utilisent std :: printf () etc. alors cela ne fonctionnera pas.


0 commentaires

4
votes

Apparemment, Freopen peut faire cela.


0 commentaires

2
votes

Si vous n'avez pas besoin d'utiliser vous-même vous-même, la chose la plus facile à faire serait de rediriger la sortie standard et une erreur standard de la ligne de commande lorsque vous démarrez votre programme.

$ myProg> / dev / null 2> & 1

Si vous DO voulez-vous utiliser vous-même, l'astuce serait de changer le courant d'utilisation qu'ils utilisent. Il y a un certain code et une discussion sur Comment faire ici . C'est vraiment trop long pour poster ici.


0 commentaires

2
votes

Depuis STDOUT (Descripteur de fichier 1) et stardr (descripteur de fichier 2) sont valables pour l'ensemble du processus et que vous ne pouvez pas faire une partie du programme, il est indiqué sur un fichier différent, il n'y a qu'un seul moyen de le faire: Utilisez DUP (2) pour les dupliquer et utilisez ces descripteurs de fichier dans votre propre code. Fermez les FD 1 et 2, Ouvrir / DEV / NULL pour écrire et utiliser DUP2 pour essayer de les définir respectivement sur 1 ou 2 si ce n'est pas déjà. Assez moche, mais ça marcherait.


0 commentaires

1
votes

Trois idées (dont aucune n'aime vraiment ...):

  • Vous pouvez modifier le tampon COUT / CERR écrivez à l'aide de rdbuf () . Vous pouvez le faire à chaque fois juste avant d'appeler une fonction dans la bibliothèque et que vous le réinitialisez ensuite (peut-être utiliser des fonctions d'emballage).

  • Vous pouvez modifier le tampon de façon permanente et utiliser différents objets COUT / CERR pour votre propre application.

  • Vous pouvez utiliser des fichiers d'en-tête standard modifiés pour la compilation des bibliothèques. Ils pourraient définir de nouveaux objets de flux globaux COUT_NEW et utiliser des macros pour redéfinir COUT TO COUT_NEW . Vous pouvez simplement dire au compilateur d'utiliser une nouvelle nouvelle version des fichiers d'en-tête uniquement pour la compilation des bibliothèques (vous n'avez donc pas à modifier leur code source).

    Comme je l'ai dit, aucune de ces solutions n'est "propre", mais vous l'avez demandé :) ...


0 commentaires

3
votes

Eh bien personne ne semble avoir frappé dessus, voici mes suggestions de liaison:

  1. Interpose libc, fournissez votre propre écrire () et filtrer la sortie sur des descripteurs de fichier 1 et 2 . .
  2. liez statiquement votre propre code contre libc, puis interpose la version partagée à StreLCH écrire () comme ci-dessus.
  3. Interpose libc, fournissant un my_write () fonction qui contourne écriture () à l'aide de dlsym () . .
  4. wrap écrire lors de la liaison des bibliothèques partagées en passant -WL, - enveloppe = écrire . Ensuite, slelch n'importe quelle sortie des descripteurs de fichier 1 et 2 dans une fonction appelée __ enveloppe_write . Les autres descripteurs de fichiers doivent faire appel à __ real_write .

    Notez que pour ceux qui ne sont pas au courant, des descripteurs de fichier 1 et 2 correspondent à stdout et stardr , qui sont finalement écrits dans le COUT / cerr machines. Souvent, ceci est implémenté COUT appels fwrite qui appelle écrire , avec des niveaux variés de tampon et de shenanigans aux différents niveaux.

    Votre meilleur pari est l'option 4, l'inconvénient est que vous devez modifier le lien final pour les bibliothèques partagées.

    Suivant Best est l'option 2 ci-dessus, l'inconvénient est votre exécutable final est beaucoup plus grosse, mais il n'est pas nécessaire d'utiliser des fonctions idiotes dans votre propre code.

    Liens

    Interposant


2 commentaires

Si vous mentionnez ld_preload ici quelque part?


Ld_preload fait partie de la technique d'interposition