使用Mupen64Plus非托管C dll API命令填充C#结构 [英] Populate C# struct using Mupen64Plus Unmanaged C dll API command

查看:90
本文介绍了使用Mupen64Plus非托管C dll API命令填充C#结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Mupen64Plus and the included m64p_test_rom.v64 file.

我正在使用 C# mupen64plus.dll C 编写的API。

I'm using C# to talk to the mupen64plus.dll API which is written in C.

问题

我正在尝试使用其API命令 M64CMD_ROM_GET_HEADER 从<$获取ROM头c $ c> m64p_test_rom.v64 ,其中包含诸如 Name Manufacturer ID 国家/地区代码。看起来该命令将数据存储在 struct 中。

I'm trying to use its API command M64CMD_ROM_GET_HEADER to get the ROM Header from m64p_test_rom.v64, which contains properties like Name, Manufacturer ID, Country code. It looks like the command stores the data in a struct.

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

The problem is that when the API command is called to populate the struct, the variables remain null, it does not populate it with new values.

我正在使用此C# API代码(来自BizHawk)与 mupen64plus.dll

I'm using this C# API code from BizHawk to talk to mupen64plus.dll.

命令

Mupen64Plus v2.0核心前端Wiki


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

命令枚举类型,指定应执行哪个命令。

Command Enumerated type specifying which command should be executed.

ParamInt:一个int可以用作命令输入的eger值。

ParamPtr:可以用作命令输入的指针。

ParamInt: An integer value which may be used as an input to the command.
ParamPtr: A pointer which may be used as an input to the command.

M64CMD_ROM_GET_HEADER

这将检索当前的标头数据打开ROM。 ROM映像必须打开。

This will retrieve the header data of the currently open ROM. A ROM image must be open.

ParamInt:指向rom_header结构的指针以接收数据

ParamPtr:rom_header的字节大小结构。

ParamInt: Pointer to a rom_header struct to receive the data.
ParamPtr: The size in bytes of the rom_header struct.






ROM标头结构



在我的 C#项目中,我创建了一个新的 struct 以匹配Mupen64Plus的 C 源代码。我不确定是否已将其从 C 正确转换为 C#


ROM Header struct

In my C# project I created a new struct to match the one in the Mupen64Plus's C source code. I'm not sure if I have converted it from C to C# correctly.

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的名称。


ROM Get Header

I'm trying to retrieve the ROM's Name.

运行API命令 M64CMD_ROM_GET_HEADER 应该填充 m64p_rom_header 结构

Running the API command M64CMD_ROM_GET_HEADER should populate the m64p_rom_header struct.

code>名称属性应返回为Marshallh(GPL)的 Mupen64Plus演示

我收到错误 ArgumentNullException:数组不能为空。 rom_header.Name 上。

当我调用命令时,ROM已打开并正在运行。

The ROM is open and running when i call the command.

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):

You have defined/passed the parameters to the method in the wrong order. The second parameter of the delegate is of type int and the third parameter is a void pointer in C and should be used to pass data as a reference. For example, you can find the following code in the link you sent (BizHawk/mupen64pluseCoreApi.cs) :

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

因此,委托的定义应如下:

So the definition of the delegate should be as the following:

[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);

这篇关于使用Mupen64Plus非托管C dll API命令填充C#结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆