2017-09-06 14 views
4

私はC++フレームワークを持っています。このフレームワークでは、C言語の関数や外部の "C"リンケージを持つC++関数に(時には自動生成される)いくつかの計算が委任されています。これらは低レベルのルーチンであり、非常に迅速かつ最小限のオーバーヘッドで評価されなければならず、通常は別々の共有オブジェクト/ DLLに存在します。DLL境界を越えてFILEオブジェクトを渡すことはできますか?

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

dlopen POSIX上またはWindows上のLoadLibrary使用してロードされた共有ライブラリに存在します:彼らの現在の署名はの線に沿って何かです。対応する関数ポインタは、POSIXではdlsym(handle, "my_generated_function")、WindowsではGetProcAddress(handle, TEXT("my_generated_function"))を使用して抽出されます。

FILEオブジェクトポインタでシグネチャを増やすのは安全で移植性がありますか? my_generated_functionを含む共有オブジェクトが共有オブジェクトをロードするコードとは異なる(しかし、バイナリ互換性のある)コンパイラでコンパイルされている可能性があること

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

注意。

+0

"C関数*または* C++関数を外部" C "リンケージで記述したとき、私はそれを暗示していませんでした。私は関数が純粋なCまたはC++コードであることを意味しました。後者の場合は、 'extern" C "'を持ちます。 – Joel

+1

私は、呼び出されたdllがexe/dllの呼び出しと同じc-runtimeを使用してコンパイルされているかどうかという事実に依存すると言いたいと思います。 –

+0

@ArtemyVysotskyこれはどういう意味ですか?同じコンパイラの2つの異なるバージョン、あるいは 'gcc'と' clang'(バイナリ互換)の組み合わせでコードをコンパイルするとどうなりますか? – Joel

答えて

5

FILE*は不透明なハンドルとして考えることができます。問題は、このハンドルの下の実際のオブジェクト、つまりFILE構造体の定義とその実装の詳細は、コンパイラ/ CRT固有であるということです。

私の知る限り、FILEの実装が、 Visual Studio 2008または2010は、VS2015または2017に含まれるものと同じです。つまり、構造(FILE)のという名前がであっても、実装の詳細は、 CRTを別のものに送る。

だから、私はないにお勧めしたいあなたはVC++コンパイラ/ CRTの同じバージョンを使用するようにクライアントを制限する場合を除き、DLLの境界でFILE*を持っています。

一方、DLLインターフェイス境界でクロスコンパイラ/ CRT互換のハンドルが必要な場合は、Win32 HANDLEタイプ(CreateFileのようなAPIから返されたもの)を使用することをお勧めします。これはOSレベルで定義されているので、特定のVC++コンパイラ/ CRTから独立しています。

あなたはFILE*からのWin32 HANDLEを取得したい場合はthis SO answerで説明したように、あなたは、_fileno_get_osfhandleを使用することができます。

関連する問題