Link to home
Start Free TrialLog in
Avatar of mittelhauser
mittelhauser

asked on

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,
                        &(iHandsA[0]),&iHandsA[1],&iHandsA[2],&iHandsA[3],&iHandsA[4],&iHandsA[5],&iHandsA[6],&iHandsA[7],&iHandsA[8],
                        &(iHandsB[0]),&iHandsB[1],&iHandsB[2],&iHandsB[3],&iHandsB[4],&iHandsB[5],&iHandsB[6],&iHandsB[7],&iHandsB[8]);

-------------------------

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?

-Jon

Avatar of mittelhauser
mittelhauser

ASKER

I presume it is obvious but what I would prefer is to pass the various int* as arrays instead of indvidually.  
ASKER CERTIFIED SOLUTION
Avatar of AvonWyss
AvonWyss
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
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...

-Jon
Have a look at this USENET discussion:
http://groups.google.com/groups?threadm=s5EBc.5342%2437.703686%40news.siol.net

I believe that this is what you are looking for.
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:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/vclrf__gc.asp

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++.
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.