Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 337
  • Last Modified:

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

0
mittelhauser
Asked:
mittelhauser
  • 6
  • 4
1 Solution
 
mittelhauserAuthor Commented:
I presume it is obvious but what I would prefer is to pass the various int* as arrays instead of indvidually.  
0
 
AvonWyssCommented:
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);

or

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

That should do the trick...
0
 
AvonWyssCommented:
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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

-Jon
0
 
AvonWyssCommented:
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.
0
 
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?

0
 
AvonWyssCommented:
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.
0
 
AvonWyssCommented:
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++.
0
 
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.
0
 
AvonWyssCommented:
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.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now