Question

I have a C++ based binary (dll) which I have written a C# Wrapper for. The dll uses a webservice which fires the callback when it's finished getting the data. I call a method with a parameter of the player's name which the webservice uses to generate the data I need. If the player is valid, the callback fires successfully and I can use the data just fine. If the player is not valid, I get a Null Reference exception from within the C++ Binary. The odd thing is, if I run the C++ code, it runs the callback just fine.

A friend and I have deduced that the likely issue is that null is being passed in from the binary and C++ can handle it but C# cannot? Given that it works fine in C++, it's unlikely to be a problem in the binary itself. Is the conversion of the callback below accurate?

C++ Callback

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# Callback

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

Happy Holidays!

Was it helpful?

Solution

Building on anthony-arnold's comment, it could be that the C++ side tries to pass NULL to the structure parameters (I've had similar issues with native code). Make the structure params IntPtr instead (without the ref keyword) and check if they are zero. If they're not zero you can get a struct out of them like so:

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
  }
}

I don't think it should be needed for the uint parameters as passing NULL from the C++ side should set them to 0(?) (I'm not sure on this, someone correct me if I'm wrong).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top