2010-10-21 2 views
24

Die Funktion fopen gibt einen Zeiger auf eine FILE Struktur zurück, die als undurchsichtiger Wert betrachtet werden sollte, ohne sich mit ihrem Inhalt oder ihrer Bedeutung zu befassen.Wie bekomme ich die Datei HANDLE aus der fopen FILE-Struktur?

Unter Windows ist die C-Laufzeitumgebung ein Wrapper der Windows-API, und die -Funktion beruht auf der CreateFile-Funktion. Die Funktion CreateFile gibt eine HANDLE zurück, die von einer anderen Windows-API verwendet wird.

Jetzt muss ich Windows API tief in einer Bibliothek verwenden, die und FILE* verwendet. Also: Gibt es eine Möglichkeit, die HANDLE von der FILE Struktur zu bekommen? Da dies compilerspezifisch ist, meine ich die MSVC-Laufzeitbibliothek.

Ich verstehe, dass dies ein hässlicher, nicht portabler Hack wäre, und das könnte kaputt gehen, wenn Microsoft das interne Format FILE ändert ... aber ich entwickle auf einem geschlossenen System (dh auf einem Windows CE Embedded System) und das Refactoring der Bibliothek wäre schwierig und zeitaufwendig.

+1

Gute Frage, ich mit dieser beschäftigt mich mehr als 2 Jahren. –

Antwort

15

Verwenden Sie _fileno gefolgt von _get_osfhandle. Vergiss nicht _close wenn du fertig bist.

EDIT: es ist mir nicht klar, dass _get_osfhandle auf WinCE unterstützt wird. Die Dokumentation für WinCE _fileno sagt jedoch, dass es ein "Datei-Handle" statt "Deskriptor" zurückgibt. YMMV, aber das deutet darauf hin, dass Sie vielleicht _fileno Rückgabewert direkt als ein Handle auf WinCE verwenden können.

EDIT: # 2 Diese Theorie wird von this person's experience unterstützt.

„Wenn Sie einen Blick auf die Header-Dateien nehmen, die ich 29 auf Jan in die Liste geschrieben Sie können sehen, wie ich die Datei-Erstellung/handle Problem behandelt. Ich habe nicht alle FILE * ersetzen Einzelteile mit . Griffe finden Sie in dem folgenden Ausschnitt aus 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 

es stellt sich heraus, dass _fileno einen Griff zurück Sie es einfach werfen müssen „..

+1

Danke, _fileno war gut genug für mein Windows CE-Problem, aber Ihre Antwort scheint tatsächlich "portabel" auf allen MS-Plattformen mit jeder Version von MSVC. – Wizard79

4

Unter Linux gibt es die int fileno(FILE *);-Funktion, die den Dateideskriptor (den, der von der Low-Level-Funktion open zurückgegeben wurde) von FILE* zurückgibt.

Ich weiß nicht, ob es für Windows gilt und gibt den GRIFF zurück?

+1

Hmm, das ist möglich: http://msdn.microsoft.com/en-us/library/ee479262.aspx gibt an, dass "_fileno Dateihandle mit Stream verknüpft". Zumindest unter Windows CE sollte es funktionieren. – Wizard79

+1

Es ist nur eine Kompatfunktion für * nix. Griffe sind Zeigergröße, 8 Bytes auf Win64. –

2

Für C, versuchen Sie diese

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

Später verwendet, sagt mir das der Handle ist ungültig für z. stdout. – imallett

Verwandte Themen