Managed strings and buffers to nonmanaged
-
I just jumped in to MC and am having some string problems. I have 2 functions in c++ that I wanted to wrap with MC to use from c#. The def are as follows.
int EncryptString (wchar_t * pszString, wchar_t * & pszResultString); int DecryptString (wchar_t * pszString, wchar_t * & pszResultString);
The first param of both is a string. the second is a string that acts as a buffer for the return value. How do I get these into MC? I want to have a managed function that will take either 2 strings or a string and a StringBuilder.void CAES::DecryptStr(String* DecString, StringBuilder* Buff) { }
What do I need to put in the function to get DecString and Buff into something I can pass DecryptString? I need Buff to hold the output and return to c# intact etc. TIAHello, Check out
System.Runtime.InteropServices.Marshal
. Specifically: theStringTo...
andPtrTo...
methods. Hope this helps, Nathan --------------------------- Hmmm... what's a signature? -
Hello, Check out
System.Runtime.InteropServices.Marshal
. Specifically: theStringTo...
andPtrTo...
methods. Hope this helps, Nathan --------------------------- Hmmm... what's a signature?Thanks for the reply. I have been working with that for a while now. I got the simple wchar_t to go easily. Do you know how to do the string builder buffer? I need it to copy to the wchar_t and then get whatever comes out back into the string builder. Also do you know of any good reading on this subject? I have found lots of stuff, just nothing more advanced than a simple string to string conversion. Thanks! This is what I have so far in the decrypt sub.
wchar_t __nogc* pStr = static_cast(Marshal::StringToHGlobalUni(EncString).ToPointer()); wchar_t __nogc* pBuf = ; //what goes here? int Ret; Ret = DecryptString(pStr,pBuf); //how do I get pBuf back into the stringbuilder
-
Thanks for the reply. I have been working with that for a while now. I got the simple wchar_t to go easily. Do you know how to do the string builder buffer? I need it to copy to the wchar_t and then get whatever comes out back into the string builder. Also do you know of any good reading on this subject? I have found lots of stuff, just nothing more advanced than a simple string to string conversion. Thanks! This is what I have so far in the decrypt sub.
wchar_t __nogc* pStr = static_cast(Marshal::StringToHGlobalUni(EncString).ToPointer()); wchar_t __nogc* pBuf = ; //what goes here? int Ret; Ret = DecryptString(pStr,pBuf); //how do I get pBuf back into the stringbuilder
To copy the StringBuilder into the pBuf, you should be able to exactly the same thing that you did with the first String.
String* pStringTemp = Buf->ToString(); wchar_t __nogc* pBuf = static_cast(Marshal::StringToHGlobalUni(pStringTemp).ToPointer());
Then to copy back into the StringBuilder just do:Buff->Remove(0,Buf->Length); // this clears the StringBuilder Buff->Append(new String(pszResultString)); // adds the result to the StringBuilder
Hope this helps get you going again... (not tested :() -Nathan --------------------------- Hmmm... what's a signature? -
To copy the StringBuilder into the pBuf, you should be able to exactly the same thing that you did with the first String.
String* pStringTemp = Buf->ToString(); wchar_t __nogc* pBuf = static_cast(Marshal::StringToHGlobalUni(pStringTemp).ToPointer());
Then to copy back into the StringBuilder just do:Buff->Remove(0,Buf->Length); // this clears the StringBuilder Buff->Append(new String(pszResultString)); // adds the result to the StringBuilder
Hope this helps get you going again... (not tested :() -Nathan --------------------------- Hmmm... what's a signature? -
Glad that I could be of help. I forgot to answer your question about reading material. I don't have any good articles off the top of my head, but a good book on the subject is: Programming with Managed Extensions for Microsoft Visual C++ .NET--Version 2003[^] Just the first chapter alone is worth the money. The author should give me a little cash, I think I have posted that book 3 times now here... oh well... I like it a lot... :-D I like MC++ but it is kind of a pain... It allows a lot of cool things to happen. Yea, legacy code support X| --------------------------- Hmmm... what's a signature?
-
Glad that I could be of help. I forgot to answer your question about reading material. I don't have any good articles off the top of my head, but a good book on the subject is: Programming with Managed Extensions for Microsoft Visual C++ .NET--Version 2003[^] Just the first chapter alone is worth the money. The author should give me a little cash, I think I have posted that book 3 times now here... oh well... I like it a lot... :-D I like MC++ but it is kind of a pain... It allows a lot of cool things to happen. Yea, legacy code support X| --------------------------- Hmmm... what's a signature?
OK I'm about to throw MC out the window. Here is my code
void CAES::EncryptStr(String* EncString, StringBuilder* Buff) { wchar_t __nogc* pStr = static_cast(Marshal::StringToHGlobalUni(EncString).ToPointer()); String* pStringTemp = ""; wchar_t __nogc* pBuf = static_cast(Marshal::StringToHGlobalUni(pStringTemp).ToPointer()); int Ret; Ret = EncryptString(pStr,pBuf); Buff->Remove(0,Buff->Length); // this clears the StringBuilder Buff->Append(new String(pBuf)); // adds the result to the StringBuilder }
This worked fine a few mins ago. NOTHING HAS CHANGED IN THE WHOLE PROJECT!!! Now I get an unhandled exception in mscorlib. It is a stack overflow exception. It happens on the Buff->Remove line. If I take it out it happens on the Buff->Append line. The only think I did was make some functions in the non managed class I have private with the private: keywork in my header. After this it broke. I removed the private keyword and it's still broke. Any ideas? Further info: It happens when I call any framework thing after comming back from the dll also. I tried to show a messagebox and it failed also. This was after the call to EncryptString. I removed the Buff-> stuff so the method would return. It doesn, but I get the exception after it gets back now. -
OK I'm about to throw MC out the window. Here is my code
void CAES::EncryptStr(String* EncString, StringBuilder* Buff) { wchar_t __nogc* pStr = static_cast(Marshal::StringToHGlobalUni(EncString).ToPointer()); String* pStringTemp = ""; wchar_t __nogc* pBuf = static_cast(Marshal::StringToHGlobalUni(pStringTemp).ToPointer()); int Ret; Ret = EncryptString(pStr,pBuf); Buff->Remove(0,Buff->Length); // this clears the StringBuilder Buff->Append(new String(pBuf)); // adds the result to the StringBuilder }
This worked fine a few mins ago. NOTHING HAS CHANGED IN THE WHOLE PROJECT!!! Now I get an unhandled exception in mscorlib. It is a stack overflow exception. It happens on the Buff->Remove line. If I take it out it happens on the Buff->Append line. The only think I did was make some functions in the non managed class I have private with the private: keywork in my header. After this it broke. I removed the private keyword and it's still broke. Any ideas? Further info: It happens when I call any framework thing after comming back from the dll also. I tried to show a messagebox and it failed also. This was after the call to EncryptString. I removed the Buff-> stuff so the method would return. It doesn, but I get the exception after it gets back now.Shouldn't you have to pass a type to the static_cast method (operator)? Like:
wchar_t __nogc* pStr = static_cast<wchar_t*>(Marshal::StringToHGlobalUni(EncString).ToPointer()); String* pStringTemp = ""; wchar_t __nogc* pBuf = static_cast<wchar_t*>(Marshal::StringToHGlobalUni(pStringTemp).ToPointer());
I have no idea if that is a problem that you are having... Also you said you changed header file stuff... Did you make sure to do a clean and rebuild? [Edit] You don't really need to do the String* pStringTemp at all... all you are doing is allocating an empty string... So you only need to declare pBuf and pass it in by reference like you are doing... Also, did you make sure to new the pBuf inside of your EncrString function? else you will be writing to a zero length char buffer...[/Edit] -Nathan P.S. about the static cast stuff... you can probably ignore me, I found that you need to use the little code project buttons to make them show up... :-O --------------------------- Hmmm... what's a signature? -
Shouldn't you have to pass a type to the static_cast method (operator)? Like:
wchar_t __nogc* pStr = static_cast<wchar_t*>(Marshal::StringToHGlobalUni(EncString).ToPointer()); String* pStringTemp = ""; wchar_t __nogc* pBuf = static_cast<wchar_t*>(Marshal::StringToHGlobalUni(pStringTemp).ToPointer());
I have no idea if that is a problem that you are having... Also you said you changed header file stuff... Did you make sure to do a clean and rebuild? [Edit] You don't really need to do the String* pStringTemp at all... all you are doing is allocating an empty string... So you only need to declare pBuf and pass it in by reference like you are doing... Also, did you make sure to new the pBuf inside of your EncrString function? else you will be writing to a zero length char buffer...[/Edit] -Nathan P.S. about the static cast stuff... you can probably ignore me, I found that you need to use the little code project buttons to make them show up... :-O --------------------------- Hmmm... what's a signature?Yeah, I did a clean build. I restored the header file from backup. No luck. Here is the kicker... I ported another class to see if it was with all of them or just this one. It works fine. And guess what, the other one works fine now also... Go figure. I have no idea what went wrong. Maybe it will do it again?? Oh well. Thanks for all your help and info.
-
Yeah, I did a clean build. I restored the header file from backup. No luck. Here is the kicker... I ported another class to see if it was with all of them or just this one. It works fine. And guess what, the other one works fine now also... Go figure. I have no idea what went wrong. Maybe it will do it again?? Oh well. Thanks for all your help and info.
-
And yet once again it won't work. I added a 3rd class that doesn't work either. an exception about a null pointer from mscorlib.
hmmm... I guess I would probably need to see your code... But check my last post about the String* and empty string... If you want to email me or something outside of here... we can try that... -Nathan --------------------------- Hmmm... what's a signature?
-
hmmm... I guess I would probably need to see your code... But check my last post about the String* and empty string... If you want to email me or something outside of here... we can try that... -Nathan --------------------------- Hmmm... what's a signature?
I eventually just made a wchar_t buffer of the right size and passed a pointer to it to the function. When it gets back it copies the buffer to the string like you had above. Works fine now. Thanks again. I'm going to pick up that book you mentioned soon.