I have dll imported. All the other parts work, but the string return value of imported method gives this:
Unhandled exception at 0x7748EA5F (ntdll.dll) in ***.exe: 0xC0000374: A heap has been corrupted (parameters: 0x774C4270).
It still returns the string, but I'm worried that this causes some other errors later on, that are hard to debug. From what I have tested, it feels like it can be anything, that is causing this.
This is my importing code:
[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));
usage
getString(Handle, 1);
This works, but it causes the error. While debugging, just pressing "continue" will allow it to process it and show the results. Result is correct.
This is how it is done in delphi dll
function GetString(Hnd,Index : Integer) : PChar; stdcall;
begin
Result:=TControl(Hnd).Stack.GetString(Index);
end;
I have same kind of code for integers, doubles, bools and everything else in the dll works, without errors. So I think it creates somekind of overflow or wrong size of memory allocation.
Note: If I create console application, it just fails, without breaking on error, if I run console without debugger ( ctrl+f5 ), it works, still without error. Heap error is generated when I call this from forms application.
TL;DR; This code works, but it shows the heap error, while returning ints, bools etc works perfectly.
Heap corruption occurs when a program damages the allocator's view of the heap. The outcome can be relatively benign and cause a memory leak (where some memory isn't returned to the heap and is inaccessible to the program afterward), or it may be fatal and cause a memory fault, usually within the allocator itself.
Check for heap corruption Most memory corruption is actually due to heap corruption. Try using the Global Flags Utility (gflags.exe) or pageheap.exe. See /windows-hardware/drivers/debugger/gflags-and-pageheap.
Overrun and underrun errors They're one of the most difficult type of heap corruption to track down, and usually the most fatal to program execution. Overrun errors occur when the program writes past the end of the allocated block.
When you return a string as a function return value of a p/invoke function the marshaller takes responsibility for freeing that memory. It assumes the memory was allocated on the COM heap, e.g. with CoTaskMemAlloc
. Your string does not meet that requirement.
IntPtr
and use Marshal.PtrToStringAnsi
to manually marshal. The question then remains as to whether the memory needs to be freed, and if so how. I cannot see all the way into your code to be sure, but I would not be surprised if you were returning PChar(s)
where s
was a local variable. That would mean that you would be returning the address of freed memory.
The bottom line here is that passing strings (or indeed arrays or other dynamic structures) from callee to caller is much more complex than passing simple value types. You are going to need to re-consider how you do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With