2017-09-06 4 views
4

Ich habe ein C++ - Framework, in dem einige Berechnungen an (manchmal automatisch generierte) C-Funktionen oder C++ - Funktionen mit externer C-Verknüpfung delegiert werden. Dies sind Low-Level-Routinen, die sehr schnell und mit minimalem Overhead ausgewertet werden müssen. Sie befinden sich normalerweise in separaten gemeinsam genutzten Objekten/DLLs. Ihre aktuelle Signatur ist etwas entlang der Linien von:Kann ich FILE-Objekt über DLL-Grenzen übergeben?

int my_generated_function(const double* input, double* output, double* work); 

, die in einer gemeinsamen Bibliothek befinden wird geladen mit dlopen auf POSIX oder LoadLibrary unter Windows. Die entsprechenden Funktionszeiger werden mit dlsym(handle, "my_generated_function") unter POSIX oder GetProcAddress(handle, TEXT("my_generated_function")) unter Windows extrahiert.

Ist es sicher und portabel, die Signatur mit einem FILE-Objektzeiger zu ergänzen?

int my_generated_function(const double* input, double* output, double* work, 
          FILE* logfile); 

Beachten Sie, dass das gemeinsame Objekt my_generated_function enthält, könnte mit einem anderen (aber binärkompatibel) Compiler als der Code kompiliert wurden, die das gemeinsame Objekt lädt.

+0

Ich habe nicht impliziert, dass, wenn ich schrieb "C-Funktionen * oder * C++ Funktionen mit externen" C "Verknüpfung". Ich meinte, dass die Funktion entweder reiner C- oder C++ - Code ist. Im letzteren Fall hat es "extern" C "". – Joel

+1

Ich würde sagen, es hängt von der Tatsache ab, ob die aufgerufene DLL mit der gleichen c-Laufzeit kompiliert wird wie der Aufruf von exe/dll –

+0

@ArtemyVysotsky Was ist die Implikation davon? Was ist, wenn der Code zum Beispiel mit zwei verschiedenen Versionen des gleichen Compilers oder einer Kombination von 'gcc' und' clang' (die binärkompatibel sind) kompiliert wird? – Joel

Antwort

5

Sie können sich die FILE* als undurchsichtigen Griff vorstellen. Das Problem besteht darin, dass das tatsächliche Objekt unter diesem Handle, mit anderen Worten, die Definition der FILE-Struktur und ihre Implementierungsdetails compiler/CRT-spezifisch sind.

Also, meines Wissens gibt es keine Garantie, dass die Datei-Implementierung von z. Visual Studio 2008 oder 2010 ist identisch mit denen, die in VS2015 oder 2017 kommen. Mit anderen Worten, auch wenn der Name der Struktur (FILE) identisch ist, können die Implementierungsdetails sehr gut von einer Version der ändern CRT zu einem anderen.

Also, würde ich vorschlagen, zu nicht ein FILE* an den DLL Grenzen haben, wenn Sie Ihre Kunden beschränken wollen die gleiche Version des Compilers/CRT VC++ zu verwenden.

Auf der anderen Seite, wenn Sie einen Cross-Compiler/CRT kompatibel Griff an der DLL-Schnittstelle Grenze benötigen, würde ich vorschlagen, den Win32-HANDLE Typen (die, die von APIs wie CreateFile zurückgegeben wird). Dies ist auf der Betriebssystemebene definiert, so dass es unabhängig von dem bestimmten VC++ - Compiler/CRT ist.

Wenn Sie die Win32 HANDLE von einem FILE* erhalten möchten, können Sie _get_osfhandle mit _fileno verwenden, wie in this SO answer erläutert.

Verwandte Themen