0

Structure in C++:

typedef struct _denom 
    { 
     CHAR       cCurrencyID[3]; 
     int       ulAmount; 
     short     usCount; 
     LPULONG    lpulValues; //pointer to array of ULONGS 
     int      ulCashBox;        
    } DENOMINAT, * LPDENOMINAT; 

Structure in C#:

[ StructLayout( LayoutKind.Sequential, 
CharSet=CharSet.Ansi, Pack=1 ) ] 
 public struct  DENOMINAT 
 { 
   [ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 ) ] 
  public char[] cCurrencyID; 
  public int ulAmount; 
  public short usCount; 
  public IntPtr lpulValues; 
  public int ulCashBox;     
} 

lpulValues is a pointer to array of ulongs and its array size is based on the usCount for eg :if uscount is 5 then in C++ it would be lpulValues = new ULONG[usCount];.

I can easily get the array values in C++ which is not been possible in C#.I dont understand how to get the array values through IntPtr. Thanks in advance.

xanatos
  • 109,618
  • 12
  • 197
  • 280
TechBrkTru
  • 346
  • 1
  • 25

1 Answers1

2

Important thing

In Windows, in C/C++, sizeof(long) == sizeof(int). So sizeof(C-long) == sizeof(C#-int). See https://stackoverflow.com/a/9689080/613130

You should be able to do:

var denominat = new DENOMINAT();

var uints = new uint[denominat.usCount];
Marshal.Copy(denominat.lpulValues, (int[])(Array)uints, 0, uints.Length);

Note that we cheat a little, casting the uint[] to a int[], but it is legal, because they differ only for the sign (see https://stackoverflow.com/a/593799/613130)

I don't think you can do it automatically with the .NET PInvoke marshaler.

To display the array:

for (int i = 0; i < uints.Length; i++)
{
    Console.WriteLine(uints[i]);
}
Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • @TechBrkTru See added lines – xanatos May 19 '15 at 10:06
  • :how will i display the array values of lpulvalues for eg: if the ulongs length is 5??? In C++ i can display it as lpulValues[0] ,lpulValue[1] ...and so on how is it possible in C# – TechBrkTru May 19 '15 at 10:07
  • Why you don't use (ulong[]) instead of (long[]) – ahmedsafan86 May 19 '15 at 10:18
  • The cast is necessary because the `Marshal.Copy` doesn't have an overload for `ulong[]`, but only for `long[]`, so I have to trick it to use the `long[]` overload for out `ulong[]` array. – xanatos May 19 '15 at 10:19
  • @xanatos:Well i get the address values when i execute the for loop .I need to access the values stored at those address – TechBrkTru May 19 '15 at 10:21
  • @TechBrkTru No, the `ulong[] ulongs` array is the array of the values that are present at the `denominat.lpulValues` – xanatos May 19 '15 at 10:22
  • @TechBrkTru Are you looking at the data in Visual Studio? right click on the data and uncheck `Hexadecimal Display` – xanatos May 19 '15 at 10:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/78174/discussion-between-xanatos-and-techbrktru). – xanatos May 19 '15 at 10:49