2

ロギングクラスを含むWindowsDLLライブラリを作成しています。そのクラスのlog関数は、テスト目的で次のようにfprintfを呼び出すだけです。

fprintf(stderr、 "デバッグ:%s \ n"、 "こんにちは");

この呼び出しは、他のプロジェクト(ライブラリを使用する)の任意のファイルの任意の関数から使用すると正常に機能しますが、ログクラスを使用してライブラリの任意の場所に配置すると、何も出力されません。
関数が正しく実行されていることがわかります(単純なexit(0);を使用してテストします)。

今でも私はc/c ++のライブラリの概念全体に少し慣れていないので、理解できないことがあるかもしれませんが、そうでなければ、なぜそれが機能しないのかわかりません。

こことグーグルで検索してみましたが、同じ問題を抱えている人は他に見つかりませんでした。
VC++2010を使用しています

編集:ライブラリからstderrを使用する代わりに、ファイルポインターを渡すというアイデアがありましたが、これにより例外がスローされます(スロー時にファイルの_tmpfnameポインターがNULLであるため、正しいかどうかはわかりません)

4

1 に答える 1

2

実稼働コードに対してこれを行うことは避けます(ただし、テストは問題ありません)。標準のI/Oストリームはアプリケーションに属し、DLLは家のゲストです。デバッグ出力を提供する場合は、アプリケーションがログ記録用のコールバック関数をセットアップできるようにします。例:

// In your DLL's header file:
typedef void (*LogFunc)(const char *, ...);
void DLLEXPORT SetLogFunction(LogFunc logFunc);

// In your DLL's source file:
LogFunc g_LogFunc;
void DLLEXPORT SetLogFunction(LogFunc logFunc)
{
    g_LogFunc = logFunc;
}

...
// Then, instead of calling fprintf(stderr, "blah"), do this:
g_LogFunc("blah");

テストのためにこれを行う場合は、に直接書き込むことができますがstderr、それが機能するためには、DLLとアプリケーションが同じバージョンのCランタイムに対してリンクされている必要があることに注意してください。Cランタイムはそれ自体がDLLであり、DLLとアプリケーションが異なるバージョンのCランタイムを指定している場合、Cランタイムの2つの別々のコピーをメモリにロードし、それぞれが意味について独自の考えを持っていることになりstderrます。それらが異なると、悪いことが起こります。

Visual Studioで、使用しているCランタイムライブラリを設定するには、プロジェクト設定を開き、[構成プロパティ]→[C / C ++]→[コード生成]→[ランタイムライブラリ]に移動し、DLLとアプリケーションの両方が正確に設定されていることを確認します。同じ値(通常、デバッグビルドとリリースビルドのどちらをビルドするかに応じて、「マルチスレッドDLL(/ MD)」または「マルチスレッドデバッグDLL(/ MDd)」)。

于 2012-08-02T23:18:04.587 に答える