使用Mupen64Plus非托管C dll API命令填充C#结构

马特·麦克马尼斯

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

我使用C#去跟mupen64plus.dll这是写在API Ç


问题

我试图使用其API命令M64CMD_ROM_GET_HEADER来从ROM头m64p_test_rom.v64,其中包含样特性NameManufacturer IDCountry code看起来该命令将数据存储在中struct

问题在于,当调用API命令填充时struct,变量保持为空,则不会使用新值填充该变量。


API

我正在使用BizHawk的C#API代码与进行交谈mupen64plus.dll

指令

Mupen64Plus v2.0核心前端Wiki

  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以匹配Mupen64PlusC源代码中的一个。我不确定是否已正确将其从转换CC#

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

Namepoperty应返回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);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章