c# to C++ - transfer an array of int*

So I was in a hurry the other day and couldn't figure out the *right* way to do something.  Instead I ended up with this lovely funtion in my .cpp library:

int HoldEmLibrary::CompareSixHands(Deck handA,                                                   Deck handB,
                    Deck handC,
                    Deck handD,
                    Deck handE,
                    Deck board,
                   int *retCount,
                   int *retHandACount,
                   int *retHandBCount,
                   int *retHandCCount,
                   int *retHandDCount,
                   int *retHandECount,
                   int *retTieCount,
                   int *HandsA0,
                   int *HandsA1,
                   int *HandsA2,
                   int *HandsA3,
                   int *HandsA4,
                   int *HandsA5,
                   int *HandsA6,
                   int *HandsA7,
                   int *HandsA8,
                   int *HandsB0,
                   int *HandsB1,
                   int *HandsB2,
                   int *HandsB3,
                   int *HandsB4,
                   int *HandsB5,
                   int *HandsB6,
                   int *HandsB7,
                   int *HandsB8,
                   int *HandsC0,
                   int *HandsC1,
                  int *HandsC2,
                  int *HandsC3,
                  int *HandsC4,
                  int *HandsC5,
                  int *HandsC6,
                  int *HandsC7,
                  int *HandsC8,
                  int *HandsD0,
                  int *HandsD1,
                  int *HandsD2,
                  int *HandsD3,
                  int *HandsD4,
                  int *HandsD5,
                  int *HandsD6,
                  int *HandsD7,
                  int *HandsD8,
                  int *HandsE0,
                  int *HandsE1,
                  int *HandsE2,
                  int *HandsE3,
                  int *HandsE4,
                  int *HandsE5,
                  int *HandsE6,
                  int *HandsE7,
                  int *HandsE8

Which is called like this from an unsafe funtion in C#:

                  int* iHandsA = stackalloc int[9];
                  int* iHandsB = stackalloc int[9];

                  for (int icnt = 0; icnt <9; icnt++)
                        iHandsA[icnt] = 0;
                        iHandsB[icnt] = 0;

                  int iCount = lib.CompareTwoHands(d1,d2,d3,&iCnt,&iH1,&iH2,&iTie,


Obviously this is fugly and leads to ugliness on both ends...but for the life of me, I couldn't figure out the right way to do it.  Help?


Who is Participating?
AvonWyssConnect With a Mentor Commented:
Well, just pass them as arrays! The marshaller does support this, just use the MarshalAs-Attribute to specify what it is:

[DllImport ("SomeDll.dll")]
public static extern void ExternalMethodWithConstantSizedArray([MarshalAs(UnmanagedType.LPArray, SizeConst=3)] Vertex[] data);


[DllImport ("SomeDll.dll")]
public static extern void ExternalMethodWithVaribaleSizedArray([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] Vertex[] data, long size);

That should do the trick...
mittelhauserAuthor Commented:
I presume it is obvious but what I would prefer is to pass the various int* as arrays instead of indvidually.  
Note that if you want to retrieve data from the external method, you can use the ref or out modifier and the In- and Out-Attributes. The marshaller then also copies data back from unmanaged space to managed space.
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

mittelhauserAuthor Commented:
I guess I need a more specific answer because I can't figure out how to apply that.

It has been awhile since I messed around with c++ but I needed to for this app.  Some more specifics, the C++ function is in managed code.  I need the C++ function to fill-in all of the ints which are passed.

Can you provide me an example declaration for both the C++ function and the C# call.  Just take a case where I want to pass some parameters (say 2 strings for the example) to a C++ function which uses those parameters to calculate 20 int values,  I need to get those 20 integers back to the C# function that called.  My current solution has the C# pass 20 int* but that is ugly and requires unsafe code...

Have a look at this USENET discussion:

I believe that this is what you are looking for.
mittelhauserAuthor Commented:
Well maybe but it doesn't seem like the solution given in the post actually works.  I get the following:

c:\code\poker\HoldEmLib\HoldEmLib.h(105): error C3162: 'int __gc *__gc * ' : __gc pointers to interior __gc pointers cannot be declared

when I try to declare a test function in the C++ lib:

void HoldEmLibrary::TestArrayPass(int __gc * __gc * pArray) like the example.

I just feel like I am making this too hard.  All I want to do is have a managed C++ function return a set of ints to a managed C# app...seems like a common thing to do...right?

Er, why are you doing "int __gc * __gc * pArray"? You only need one __gc * - the one that points to the start of the array, right? And this you can then use as ref or out (when you apply the OutAttribute on the C++ code) in the C# part.
Here's the MSDN reference to the different __gc usages:

I'm sorry that I can't provide you with a working example, but I don't use C++ and have just been importing exported dll functions using the .NET marshaller so far, thus my first comment since I didn't realize you were talking of managed C++.
mittelhauserAuthor Commented:
Well I solved the problem by moving the C++ functions I needed into an unmanaged DLL and using the orginal suggestion.  Not really a true solution but it worked for me...I'll award you the points.
Thank you. As I said, I'm sorry, but I haven't used managed C++, so I don't really have a clue about your specific question with managed C++. But I'm glad it worked with unmanaged code.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.