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::CompareSixH ands(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],&iHand sA[4],&iHa ndsA[5],&i HandsA[6], &iHandsA[7 ],&iHandsA [8],
&(iHandsB[0]),&iHandsB[1], &iHandsB[2 ],&iHandsB [3],&iHand sB[4],&iHa ndsB[5],&i HandsB[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
int HoldEmLibrary::CompareSixH
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,
&(iHandsA[0]),&iHandsA[1],
&(iHandsB[0]),&iHandsB[1],
-------------------------
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
ASKER
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
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.
http://groups.google.com/groups?threadm=s5EBc.5342%2437.703686%40news.siol.net
I believe that this is what you are looking for.
ASKER
Well maybe but it doesn't seem like the solution given in the post actually works. I get the following:
c:\code\poker\HoldEmLib\Ho ldEmLib.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::TestArrayPa ss(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?
c:\code\poker\HoldEmLib\Ho
when I try to declare a test function in the C++ lib:
void HoldEmLibrary::TestArrayPa
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++.
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++.
ASKER
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.
ASKER