簡體   English   中英

使用Mupen64Plus Unmanaged C dll API命令填充C#struct

[英]Populate C# struct using Mupen64Plus Unmanaged C dll API command

我正在使用Mupen64Plus和附帶的m64p_test_rom.v64文件。

我使用C#去跟mupen64plus.dll這是寫在C API。


問題

我正在嘗試使用其API命令M64CMD_ROM_GET_HEADERm64p_test_rom.v64獲取ROM標頭,其中包含NameManufacturer IDCountry code等屬性。 看起來該命令將數據存儲在struct

問題是,當調用API命令來填充struct ,變量保持為空,它不會使用新值填充它。


API

我使用這個C# API代碼從BizHawk交談mupen64plus.dll

命令

Mupen64Plus v2.0核心前端維基

  1. CoreDoCommand(m64p_command命令,int ParamInt,void * ParamPtr)

    命令枚舉類型,指定應執行的命令。

    ParamInt:一個整數值,可用作命令的輸入。
    ParamPtr:一個指針,可用作命令的輸入。

  2. M64CMD_ROM_GET_HEADER

    這將檢索當前打開的ROM的標題數據。 必須打開ROM映像。

    ParamInt:指向rom_header結構的指針, 用於接收數據
    ParamPtr:rom_header結構的大小(以字節為單位)。


ROM標頭結構

在我的C#項目中,我創建了一個新的struct來匹配Mupen64Plus的C源代碼中的結構。 我不確定我是否正確地將它從C轉換為C#

Mupen64Plus C m64p_types.h

typedef struct
{
   uint8_t  init_PI_BSB_DOM1_LAT_REG;  /* 0x00 */
   uint8_t  init_PI_BSB_DOM1_PGS_REG;  /* 0x01 */
   uint8_t  init_PI_BSB_DOM1_PWD_REG;  /* 0x02 */
   uint8_t  init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
   uint32_t ClockRate;                 /* 0x04 */
   uint32_t PC;                        /* 0x08 */
   uint32_t Release;                   /* 0x0C */
   uint32_t CRC1;                      /* 0x10 */
   uint32_t CRC2;                      /* 0x14 */
   uint32_t Unknown[2];                /* 0x18 */
   uint8_t  Name[20];                  /* 0x20 */
   uint32_t unknown;                   /* 0x34 */
   uint32_t Manufacturer_ID;           /* 0x38 */
   uint16_t Cartridge_ID;              /* 0x3C - Game serial number  */
   uint16_t Country_code;              /* 0x3E */
} m64p_rom_header;

我的C#結構

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct m64p_rom_header
{
    public byte init_PI_BSB_DOM1_LAT_REG;  /* 0x00 */
    public byte init_PI_BSB_DOM1_PGS_REG;  /* 0x01 */
    public byte init_PI_BSB_DOM1_PWD_REG;  /* 0x02 */
    public byte init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
    public uint ClockRate;                 /* 0x04 */
    public uint PC;                        /* 0x08 */
    public uint Release;                   /* 0x0C */
    public uint CRC1;                      /* 0x10 */
    public uint CRC2;                      /* 0x14 */
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public uint[] Unknown;                 /* 0x18 */
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public byte[] Name;                    /* 0x20 */
    public uint unknown;                   /* 0x34 */
    public uint Manufacturer_ID;           /* 0x38 */
    public ushort Cartridge_ID;            /* 0x3C - Game serial number  */
    public ushort Country_code;            /* 0x3E */
};

非托管功能指針

我添加了一個新的委托聲明,因此我可以使用API​​的CoreDoCommand()函數和M64CMD_ROM_GET_HEADER命令。

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate m64p_error CoreDoCommandStruct(m64p_command Command, m64p_rom_header ParamInt, ref int ParamPtr);
CoreDoCommandStruct m64pCoreDoCommandStruct;

ROM獲取標題

我正在嘗試檢索ROM的名稱。

運行API命令M64CMD_ROM_GET_HEADER應該填充m64p_rom_header struct

Name Mupen64Plus Demo by Marshallh (GPL)應該Mupen64Plus Demo by Marshallh (GPL)作為Mupen64Plus Demo by Marshallh (GPL)返回。

我得到錯誤ArgumentNullException: Array cannot be null. rom_header.Name

當我調用命令時,ROM打開並運行。


public m64p_rom_header rom_header;

public String ROMGetHeader()
{
    // Get size of ROM Header struct
    int size = Marshal.SizeOf(typeof(m64p_rom_header)); // returns value of 20?

    // API ROM Get Header Command
    // Question: Populates all variables in the m64p_rom_header struct?
    m64pCoreDoCommandStruct(m64p_command.M64CMD_ROM_GET_HEADER, rom_header, ref size);

    // Return the byte Array and convert to String
    return System.Text.Encoding.Default.GetString(rom_header.Name); // <-- Error: Array null
}

您已按錯誤的順序將參數定義/傳遞給方法。 委托的第二個參數是int類型,第三個參數是C中void指針 ,應該用於傳遞數據作為引用。 例如,您可以在發送的鏈接中找到以下代碼(BizHawk / mupen64pluseCoreApi.cs):

// Pass the rom to the core
result = m64pCoreDoCommandByteArray(m64p_command.M64CMD_ROM_OPEN, rom.Length, rom);

因此委托的定義應如下所示:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate m64p_error CoreDoCommandStruct(m64p_command Command, int ParamInt, ref m64p_rom_header ParamPtr);
CoreDoCommandStruct m64pCoreDoCommandStruct;

以及您使用它的方式應如下所示:

m64pCoreDoCommandStruct(m64p_command.M64CMD_ROM_GET_HEADER, size, ref rom_header);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM