3

特定の文字列を返す関数を含むDLLをCで作成する必要があります(文字列を表すcharバッファーへのポインターとして)。DLL内の関数は繰り返し呼び出され、異なるスレッドで実行されます。

正しいことは、関数にcharバッファーを割り当て、戻りバッファーが使用された後、呼び出し元の環境で割り当てられたバッファーを解放することです。

// DLL function

char *getString() {
    char *buffer = (char *)malloc(STRING_LEN);
    // fill buffer with some string
    return buffer;
}

残念ながら、dll内の関数を呼び出すプログラミング環境には、返されるバッファを解放するメカニズムがないため、メモリリークが発生します。

このような状況でメモリリークを発生させずに文字列を返すにはどうすればよいですか?

4

2 に答える 2

3

DLL は個別のヒープを使用するため、DLL に割り当てられたものは、同じ DLL によって割り当て解除される必要があります。

hmjd が言ったように、1 つのオプションは、バッファを削除するためにバッファを提供した DLL に戻すことです。したがって、dll は割り当て解除機能を提供します。

私が気に入っている他のオプションは、呼び出し元のプログラムがメモリ自体を提供することです。たとえば、呼び出しプログラムでバッファーを割り当てて、バッファーの長さを含めて渡し、バッファーが十分に大きくない場合、必要な長さで dll 関数が失敗するようにします。このような:

bool doStuff( char* buffer, int& len )
{
    if ( len < tooSmall() )
    {
       len = requiredLength();
       return false;
    }

    // fill the buffer here somehow

    return true;
}

その後、通常どおり呼び出し側プログラムでバッファーを管理できます。これの利点の 1 つは、呼び出し元プログラムがバッファを再利用することが理にかなっている場合に簡単にできることです。

于 2012-10-22T21:03:23.000 に答える
2

呼び出し元がバッファを提供するように API を変更することは可能ですか? maxStringLength定数(またはヘッダーまたは関数のマクロ)を追加して、呼び出し元が常に戻り文字列に十分なスペースを割り当てることができるようにします。

// DLL
const size_t maxStringLength = STRING_LEN;
char *getString( char *buffer, size_t buffer_size) {
    // fill buffer with some string
    return buffer;
}

// calling code
char *my_buffer = malloc( maxStringLength);
if (my_buffer != NULL)
{
    getString( my_buffer, maxStringLength);
    // use string
    free( my_buffer);
}
于 2012-10-22T21:02:53.260 に答える