Carlos Landeras
Carlos Landeras

Reputation: 11063

C# PInvoke - Function returning char* and with reference char* parameter

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

Answers (2)

stark
stark

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

Felice Pollano
Felice Pollano

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

Related Questions