我有以下标题和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;
}
我已经编译了我的DLL,并且我正在尝试使用以下代码从C#创建一个PInvoke:
[DllImport("LndNativeAssembly.dll", EntryPoint = "?GetRamMegabytes@HardWare@Utils@@SAPADAAPAD@Z", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr GetRamMegaBytes(IntPtr freemem);
我正在尝试使用以下方法调用本机函数:
IntPtr free = IntPtr.Zero;
IntPtr res = GetRamMegaBytes(free);
我收到了这个错误:
尝试读取或写入受保护的内存。这通常是一个 表明其他内存已损坏。
答案 0 :(得分:2)
这是写入未分配的内存。
sprintf(TotalMb,"%f",freeMemFloat);
你可以在例程中使用new分配内存并在调用者中释放它,或者你可以在例程中有一个固定的缓冲区(不是线程安全的)。
答案 1 :(得分:2)
这是因为Free是函数尝试编写的目标,并且您传递 NULL ,从而产生GPF。问题是你如何编写PInvole签名。试试:
public static extern IntPtr GetRamMegaBytes(StringBuilder freemem);
并将创建的字符串构建器传递给函数。