0

I've been trying to pass information to/from c# into a c++ dll. I'm not able to alter the dll at all.

Basically, i've found a method that works - but i don't quite understand why this method works, when others don't. If i can get some sort of understanding, that would be great.

Here's my working code:

public class Helper
{
  [DllImport("C:/abc/abc.dll")]
  static extern int DLL_GetData(ref keyData key, IntPtr stringData);
  // the ref is just a pointer passed in, but is not modified in the dll. the stringData is filled in by the dll, which we then marshal back into a struct      

  public string GetStringData()
  {
    keyData key = new keyData();

    key.DataKey.text = "5555555";
    key.ProdKey.length = 7;

    key.Version.text = "2012";
    key.Version.length = 4;

    IntPtr keyPtr = Marshal.AllocHGlobal(Marshal.SizeOf(key));

    stringData data = new stringData();
    IntPtr dataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(data));

    int status = DLL_GetData(ref key, dataPtr);
    data = (stringData)Marshal.PtrToStructure(dataPtr, typeof(stringData));

    return data.text;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct keyData
  {
    [MarshalAs(UnmanagedType.Struct)]
    public stringData DataKey;
    [MarshalAs(UnmanagedType.Struct)]
    public stringData Version;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct stringData
  {
    [MarshalAs(UnmanagedType.LPWStr)]
    public string text;
    public int length;
  }
}

So, if i call GetStringData(), i am able to get the required string back that i wanted. However, i'm confused as to why only using ref for the keyData, and IntPtr for the stringData should work for me?

I have tried using both parameters as ref values, and both as IntPtrs, but to no avail. It was only by chance really that i tried using one as a ref and one as an IntPtr. The question really is - why is this the case? I'd really like to understand why this is...... hopefully i've included enough code and information.

Here is the dll function method:

DLL_GetData(KEYDATA *key, STRINGDATA *data);

Now, i have no idea what is in the body of this function (otherwise i would post it). But i'm expected to try and use it.

So STRINGDATA struct:

typedef struct STRINGDATA
{
   unsigned short* text;
   int length; 
}STRINGDATA;

and KEYDATA struct:

typedef strut
{
   STRINGDATA key;
   STRINGDATA ver;
} KEYDATA;
user2477533
  • 201
  • 1
  • 2
  • 10
  • Can you post the c/c++ source of the *.dll file? I would expect that keyData is declared as a struct passed by value and stringData is declared as a pointer to a char array (LWSTR). You can check this http://msdn.microsoft.com/en-us/library/awbckfbz.aspx – user743414 Sep 27 '13 at 08:42
  • You are asking us to debug code we cannot see, that's not a reasonable request. Get rid of UnmanagedType.Struct, use [In,Out] on the stringData argument. Or just use what works, don't forget to call Marshal.FreeHGlobal(). – Hans Passant Sep 27 '13 at 10:57
  • You said you tried passing both parameters using `ref`, and it didn't work. Can you post what you tried (the actual code), as well as in what sense it "didn't work"? What kind of error dit you get? – Kris Vandermotten Sep 27 '13 at 14:48

0 Answers0