C++ C# 包装器空异常错误

C++ to C# Wrapper Null Exception Error

本文关键字:异常 错误 包装 C++      更新时间:2023-10-16

我有一个基于C++的二进制文件(dll),我已经为它编写了一个C#包装器。 dll 使用 Web 服务,该服务在完成获取数据后触发回调。 我调用一个带有玩家名称参数的方法,Web 服务使用该参数生成我需要的数据。 如果播放器有效,则回调成功触发,我可以很好地使用数据。 如果播放器无效,我会从C++二进制文件中收到空引用异常。 奇怪的是,如果我运行C++代码,它会很好地运行回调。

我和一位朋友推断,可能的问题是 null 是从二进制传入的,C++可以处理它,但 C# 不能? 鉴于它在C++中工作正常,因此在二进制文件本身中不太可能成为问题。 下面回调的转换准确吗?

C++ 回调

void (game_CALLBACK *on_game_info)(const game_player_array *teammates, unsigned int teammates_array_size,
                                          const game_player_array *opponents, unsigned int opponents_array_size,
                                          const game_hero_array *team_banned_hero,
                                          unsigned int team_banned_hero_size,
                                          const game_hero_array *opponent_banned_hero,
                                          unsigned int opponent_banned_hero_size,
                                          const char *message);

C# 回调

 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void game_services_callback_on_game_info(
        ref game_summoner_array teammates, uint teammates_array_size,
        ref game_summoner_array opponents, uint opponents_array_size,
        ref game_champion_array team_banned_hero, uint team_banned_hero_size,
        ref game_champion_array opponent_banned_hero, uint opponent_banned_hero_size,
        [In] [MarshalAs(UnmanagedType.LPStr)] string message);

节日快乐!

基于安东尼-阿诺德的评论,可能是C++方试图将 NULL 传递给结构参数(我在本机代码中遇到了类似的问题)。使结构参数改为 IntPtr(不带 ref 关键字)并检查它们是否为零。如果它们不为零,你可以像这样从中得到一个结构:

private static void Handler(IntPtr structPointer)
{
  if (structPointer == IntPtr.Zero)
  {
    // struct is NULL (0)
  }
  else // valid struct
  {
    MyStruct structure;
    structure = System.Runtime.InteropServices.Marshal.PtrToStructure(
      structPointer,
      typeof(MyStruct));
    // do work with structure
  }
}

我认为uint参数不需要它,因为从C++端传递 NULL 应该将它们设置为 0(?) (我不确定这一点,如果我错了,有人纠正我)。