2011-05-21 11 views
2

gccコンパイラを使用してCで.dllファイルをコーディングしているときに奇妙な問題が発生し、MSVCとVisual Studioで使用しようとしました。 .dllは正しくコンパイルされ、コンパイルされ、gccにリンクされたテストプログラムによって正しく使用されます。 しかし、Visual Studioで.dllを使用しようとすると、私は奇妙なランタイムクラッシュを取得します。私は問題を特定し、なぜこれが起こっているのかについてのあなたの意見を感謝します。dll内からメインプログラムメモリを解放してVisual Studio 2010を破棄します

テストプログラムでは、バッファを割り当て、何らかの方法で(ユーザーに応じて)バッファを作成してからバッファを返す関数があります。ユーザーはそれを自分で実装する必要があります。以下のような何か:

float* decode(void* data, int dataSize, int par1, int par2,int par3) 
{ 

    //allocate the memory for the data 
    float* d = (float*)malloc(sizeof(float)*dataSize); 

    //do something to populate the data here 

    //return data 
    return d; 
} 

dllがバッファ*実際に使用-rmade関数に関数ポインタを取り、そのフロートを得るためにそれを使用する2つの機能があります。次に、.dllはこの関数を使用してデータを作成して使用し、使用後に解放します。以下のような

何か:

void DLL_Func(void* data,unsigned int inputPN,float* (*decode)(void*,int,int,int,int)) 
{ 

    //use the user-made decode function 
    float* nData = (*decode)(data,inputPN,par1,par2,par3); 

    //do stuff here 

    //before returning free the data buffer since it is no longer needed 
    free(nData) //<--- Crushes the program only in Visual Studio 
} 

さて、私は()が自由に問題を単離しました。私は推測

Unhandled exception at 0x7714e1fe in vstudiotest.exe: 0xC0000005: Access violation reading location 0x1e6dca5e. 

は私のdllが何MSVCコンパイラのために禁止されることを意味します。私はgccのコンパイルされたプログラムからの私のDLLを使用しますが、MSVCコンパイルされたプログラムは、その時点でつぶし、これを与える場合は正常に動作します。これはちょうどいくつかのMSVCの奇妙なものか、GCCも挫折していますが、将来この問題を抱えて私を拷問しないでしょうか?

もちろん、解決策は何とかそれを変更することです。バッファは.dllではなくユーザーによって解放されますが、これが最初に起こった理由を理解したいと思います。

答えて

3

同じCRTでメモリを割り当てて解放する必要があります。これは一般的に、これらのタイプの問題を避けるために割り当てられた同じモジュールでメモリを解放しようとするべきであることを意味します。これが可能でない場合、 CRTの同じバージョンにリンクする必要があります。

MSVCは、異なるバージョンのMS CRTにリンクしようとすると文句を言いますが、MSVCが知らない別のバージョンにリンクしていると思います。

+2

ライブラリ内のメモリを割り当ててプログラム内で解放する必要がある場合(またはその逆)には、ライブラリを初期化するときに 'malloc'と' realloc'への関数ポインタを提供する必要がありますまたは少なくともそれらを使用する関数を呼び出す前に)。これは実際には、mallocとfreeを別々のモジュールで行う必要がない場合でも、(たとえば)カスタムアロケータを使用するプログラムは、ライブラリにそのアロケータを使用させることができるので、 –

+0

あなたのコメントのためにYaurとDavidXありがとうございました。はい、私はあなたが正しいと思います。私はそれを疑った。この例では、メモリがdllの内部でインスタンス化され、dllが解放されたことを確認したので、今は安全です。 他のオプションが利用できない場合は、David Xのアイデアはかなりいいです。 – Lefteris

関連する問題