3

ここに示すように、Graphviz を P/Invoking しています。私がそのブログ エントリを書いたとき、コードは問題なく動作しました。HttpModule今、そのコードを使用して Graphviz グラフをレンダリングするをまとめていますが、 AccessViolationExceptionat agmemread.

// Native signature
Agraph_t agmemread(char *);

// P/Invoke Signature
[DllImport(LIB_GRAPH)]
private static extern IntPtr agmemread(string data);

// Usage
IntPtr g = agmemread(data);

私が言ったように、これは以前は完全に機能していました。しかし今、私は自分のコードを何にも動作させることができません。同じコードに基づく古い Graphviz アプリでさえ、もう機能しません。

これを引き起こす可能性のある変更は何ですか?Graphviz の新しいバージョンなどもダウンロードしていないので、DLL はすべて同じです。

編集:に変更しようとしstringましStringBuilderたが、同じ結果が得られました。次に、MarshalAs属性を追加しました。

static extern IntPtr agmemread([MarshalAs(UnmanagedType.LPWStr)] string data);

これで は取得できなくなりましたAccessViolationExceptionが、Graphviz は文字列を正しく読み取ることができず、null ポインターを返します。

4

1 に答える 1

6

アンマネージ コードがアクセス違反を生成し始めるために、C# から多くの支援を必要とすることはめったにありません。P/Invoke 署名に問題はありません。それが原因ではありません。

アンマネージ コードでの AV の最も一般的な原因は、ヒープの破損です。C/C++ コードにはガベージ コレクターがないため、メモリを明示的に管理する必要があります。メモリの解放 (またはリーク) を処理する必要があるだけでなく、正しいサイズを割り当て、割り当てられたメモリに書き込むコードが割り当てられたメモリ ブロックの末尾を超えて書き込まれないことを確認する必要があります。すでに解放されているメモリに書き込みます。最後の要件は、C/C++ コードがしばしば失敗する場所です。

ヒープの破損の問題は、診断が非常に難しいことです。しばらく気付かないことがあります。典型的な被害は、内部ヒープ構造が侵害されたり、別のヒープ割り当てのデータが上書きされたりすることです。後でヒープ ブロックが解放されるか、上書きされたデータが使用されるまで、問題は発生しません。例外を生成するコードは、以前に行われた損害に対して実際には責任を負いません。これは、問題の原因を見つけようとして間違った方向に進んでしまいます。

本当のトラブルメーカーを見つけるのは非常に困難です。何がうまくいかなかったのかを突き止めるためのパンくずリストがいくつかあるだけです。C/C++ ソース コードがある場合は非常に困難ですが、デバッグ アロケーターを使用してデバッグ ビルドで実行すると役立ちます。ソースコードが無いと無理です。

以前に行った呼び出しから API の使用に関する問題を特定できない限り、この問題を実際に解決するには、ベンダーまたはサポート グループからの支援が必要になります。幸運を。

于 2010-01-30T09:11:36.810 に答える