Kat*_*atu 4 c# delphi dllimport
我已经导入了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));
Run Code Online (Sandbox Code Playgroud)
用法
getString(Handle, 1);
Run Code Online (Sandbox Code Playgroud)
这有效,但它会导致错误.在调试时,只需按"继续"将允许它处理它并显示结果.结果是对的.
这是在delphi dll中完成的
function GetString(Hnd,Index : Integer) : PChar; stdcall;
begin
Result:=TControl(Hnd).Stack.GetString(Index);
end;
Run Code Online (Sandbox Code Playgroud)
我有相同类型的整数,双精度,bool和dll中的其他所有代码,没有错误.所以我认为它会产生一些溢出或错误的内存分配大小.
注意:如果我创建控制台应用程序,它只是失败,没有中断错误,如果我运行没有调试器的控制台(ctrl + f5),它工作,仍然没有错误.当我从表单应用程序调用它时生成堆错误.
TL; DR; 这段代码有效,但它显示了堆错误,而返回int,bools等工作完美.
当您返回一个字符串作为函数返回值的ap/invoke函数时,marshaller负责释放该内存.它假定内存是在COM堆上分配的,例如CoTaskMemAlloc.您的字符串不符合该要求.
IntPtr并使用Marshal.PtrToStringAnsi手动编组.那么问题仍然是内存是否需要被释放,如果是这样的话.我不能看到所有的方式进入你的代码可以肯定的,但如果你是回来时,我不会感到惊讶,PChar(s)这里s是一个局部变量.这意味着你将返回释放内存的地址.
这里的底线是将字符串(或实际上是数组或其他动态结构)从被调用者传递给调用者比传递简单值类型复杂得多.您将需要重新考虑如何执行此操作.
| 归档时间: |
|
| 查看次数: |
1427 次 |
| 最近记录: |