2010-10-21 4 views
24

La fonction fopen renvoie un pointeur vers une structure FILE, ce qui doit être considéré comme une valeur opaque, sans traiter de son contenu ou de sa signification.Comment obtenir le fichier HANDLE à partir de la structure FICHIER FICHIER?

Sous Windows, le runtime C est un wrapper de l'API Windows et la fonction fopen repose sur la fonction CreateFile. La fonction CreateFile renvoie un HANDLE, qui est utilisé par une autre API Windows.

Maintenant, j'ai besoin d'utiliser l'API Windows au cœur d'une bibliothèque qui utilise fopen et FILE*. Donc: existe-t-il un moyen d'obtenir le HANDLE de la structure FILE? Comme c'est spécifique au compilateur, je veux dire sur la bibliothèque d'exécution de MSVC. Je comprends que ce serait un hack laid, non portable, et qui pourrait cassé si Microsoft change le format interne de FILE ... mais je développe sur un système fermé (par exemple sur un système Windows CE embarqué) et refactoriser la bibliothèque serait difficile et prendrait du temps.

+1

Grande question, je me suis occupé avec celui-ci moi-même il y a plus de 2 ans. –

Répondre

15

Utilisez _fileno suivi de _get_osfhandle. Ne pas oublier de _close quand vous avez terminé.

EDIT: il n'est pas clair pour moi que _get_osfhandle est supporté sur WinCE. Cependant, les documents pour WinCE _fileno indiquent qu'il renvoie un "handle de fichier" plutôt que "descriptor". YMMV mais cela suggère que vous pouvez simplement utiliser la valeur de retour _fileno directement comme un handle sur WinCE.

EDIT: # 2 Cette théorie est supportée par this person's experience.

« Si vous regardez les fichiers d'en-tête que j'ai posté à la liste le 29 Jan vous pouvez voir comment j'ai traité le problème de création/poignée de dossier. Je n'ai pas de remplacer tous FILE * articles avec . Voir l'extrait gère suivant de fileio.cpp:

#ifndef q4_WCE 

    FlushFileBuffers((HANDLE) _get_osfhandle(_fileno(_file))); 
    HANDLE h = ::CreateFileMapping((HANDLE) 
_get_osfhandle(_fileno(_file)), 
         0, PAGE_READONLY, 0, len, 0); 
#else 

    FlushFileBuffers((HANDLE) _fileno(_file)); 
    HANDLE h = ::CreateFileMapping((HANDLE) _fileno(_file), 
        0, PAGE_READONLY, 0, len, 0); 
#endif //q4_WCE 

il se trouve que _fileno retourne une poignée il vous suffit de le jeter « ..

+1

Merci, _fileno était assez bon pour mon problème Windows CE, mais votre réponse semble réellement "portable" sur toutes les plates-formes MS avec une version de MSVC. – Wizard79

4

Sous Linux, la fonction int fileno(FILE *); renvoie le descripteur de fichier (celui qui a été renvoyé par la fonction open de bas niveau) à partir du FILE*.

Je ne sais pas si cela s'applique à Windows et renvoie la poignée cependant?

+1

Hmm, c'est possible: http://msdn.microsoft.com/en-us/library/ee479262.aspx indique que "_fileno obtient le handle de fichier associé au flux". Au moins sur Windows CE, cela devrait fonctionner. – Wizard79

+1

C'est juste une fonction compat pour * nix. Les poignées ont une taille de pointeur de 8 octets sur Win64. –

2

Pour C, essayez cette

HANDLE foo = (HANDLE)_get_osfhandle(fileno(fopen("bar.txt", "w"))); 
+0

Utilisé plus tard, cela me dit que le handle est invalide, par exemple. stdout. – imallett

Questions connexes