dllをインポートしました。他のすべての部分は機能しますが、インポートされたメソッドの文字列の戻り値は次のようになります。
***。exeの0x7748EA5F(ntdll.dll)で未処理の例外:0xC0000374:ヒープが破損しています(パラメーター:0x774C4270)。
それでも文字列が返されますが、後でデバッグが難しい他のエラーが発生するのではないかと心配しています。私がテストしたことから、それは何でもあり得るように感じます、それはこれを引き起こしています。
これは私のインポートコードです:
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private delegate String GetStringDelegate(int handle, int index);
private static GetStringDelegate getString { get; set; }
var addressOfGetString = NativeMethods.GetProcAddress(_handle, "GetString");
getString = (GetStringDelegate)Marshal.GetDelegateForFunctionPointer(addressOfGetString, typeof(GetStringDelegate));
使用法
getString(Handle, 1);
これは機能しますが、エラーが発生します。デバッグ中に「続行」を押すだけで、デバッグを処理して結果を表示できます。結果は正しいです。
これはdelphidllで行われる方法です
function GetString(Hnd,Index : Integer) : PChar; stdcall;
begin
Result:=TControl(Hnd).Stack.GetString(Index);
end;
整数、倍精度浮動小数点数、ブール値などの同じ種類のコードがあり、dll内の他のすべてがエラーなしで機能します。ですから、それはある種のオーバーフローや間違ったサイズのメモリ割り当てを生み出すと思います。
注:コンソールアプリケーションを作成すると、エラーが発生せずに失敗します。デバッガーなしでコンソールを実行すると(ctrl + f5)、エラーなしで動作します。フォームアプリケーションからこれを呼び出すと、ヒープエラーが生成されます。
TL; DR; このコードは機能しますが、ヒープエラーを示し、int、boolなどを返すことは完全に機能します。
ap / invoke関数の関数戻り値として文字列を返す場合、マーシャラーはそのメモリを解放する責任を負います。これは、メモリがCOMヒープに割り当てられていることを前提としていますCoTaskMemAlloc
。文字列がその要件を満たしていません。
IntPtr
するMarshal.PtrToStringAnsi
ために使用できます。その場合、メモリを解放する必要があるかどうか、および解放する必要がある場合はどのように解放する必要があるかという問題が残ります。確かにあなたのコードを完全に理解することはできませんが、ローカル変数がPChar(s)
どこs
にあるかを返していても驚かないでしょう。これは、解放されたメモリのアドレスを返すことを意味します。
ここで重要なのは、呼び出し先から呼び出し元に文字列(または実際には配列やその他の動的構造)を渡すことは、単純な値型を渡すよりもはるかに複雑であるということです。これをどのように行うかを再検討する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加