У меня есть следующий заголовок и 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 скомпилирована, и я пытаюсь сделать PInvoke из C # с помощью следующего кода:
[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);
И я получаю эту ошибку:
Попытка чтения или записи в защищенную память. Это часто
признак того, что другая память повреждена.
Это запись в нераспределенную память.
sprintf(TotalMb,"%f",freeMemFloat);
Вы можете либо выделить память с помощью new в подпрограмме и освободить ее в вызывающей программе, либо у вас может быть фиксированный буфер в подпрограмме (не поточно-ориентированный).
Это потому, что Free является целью, в которой функция пытается написать, а вы передаете НОЛЬ, это приводит к GPF. Проблема в том, как вы написали подпись PInvole. Попробуйте с:
public static extern IntPtr GetRamMegaBytes(StringBuilder freemem);
и передать созданный построитель строк в функцию.