Reputation: 11063
I have the following header and CPP:
"Utils.h"
__declspec(dllexport) static char* GetRamMegabytes(char* &FreeMemory);
"Utils.cpp"
char* Utils::HardWare::GetRamMegabytes(char* &FreeMemory)
{
char* TotalMb = "";
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
float freeMemFloat = ((float)statex.ullAvailPhys/1024/1024);
float value =((float)statex.ullTotalPhys/1024/1024);
sprintf(FreeMemory,"%f",value);
sprintf(TotalMb,"%f",freeMemFloat);
return TotalMb;
}
I have my DLL compiled and I'm trying to make a PInvoke from C# with the following code:
[DllImport("LndNativeAssembly.dll", EntryPoint = "?GetRamMegabytes@HardWare@Utils@@SAPADAAPAD@Z", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr GetRamMegaBytes(IntPtr freemem);
I'm trying to call the native function using:
IntPtr free = IntPtr.Zero;
IntPtr res = GetRamMegaBytes(free);
And I get this error:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Upvotes: 2
Views: 963
Reputation: 13189
This is writing to unallocated memory.
sprintf(TotalMb,"%f",freeMemFloat);
You can either allocate memory using new in the routine and free it in the caller, or you can have a fixed buffer in the routine (not thread-safe).
Upvotes: 2
Reputation: 33252
This is because Free is the target in which the function is trying to write, and you are passing NULL, that results in a GPF. The problem is how you wrote the PInvole signature. Try with:
public static extern IntPtr GetRamMegaBytes(StringBuilder freemem);
and pass a created string builder to the function.
Upvotes: 2