2

次のヘッダーと CPP があります。

「Utils.h」

__declspec(dllexport) static char* GetRamMegabytes(char* &FreeMemory);

「ユーティリティ.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);

そして、私はこのエラーを受け取ります:

保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています。

4

2 に答える 2

2

これは、Freeが関数が書き込もうとしているターゲットであり、NULLを渡しているため、GPFが発生するためです。問題は、PInvole署名をどのように記述したかです。試してみてください:

public static extern IntPtr GetRamMegaBytes(StringBuilder freemem);

作成した文字列ビルダーを関数に渡します。

于 2012-11-12T14:39:03.003 に答える
2

これは未割り当てメモリへの書き込みです。

sprintf(TotalMb,"%f",freeMemFloat);

ルーチンで new を使用してメモリを割り当て、呼び出し元で解放するか、ルーチンで固定バッファを使用することができます (スレッドセーフではありません)。

于 2012-11-12T14:35:26.227 に答える