C# application crashes after I get a string from a C++ dll
-
Friday, March 16, 2012 2:59 AM
Hi there,
I try to get a string from my C++ dll in C# application.
My code snippet is below:
===== C++ dll =====
__declspec(dllexport) void GetSzString(char** pszString, size_t nLength)
{
if(*pszString == NULL) {
return;
}strcpy_s(*pszString, nLength, "Hello,World");
}===== C# App =====
class Program
{
[DllImport("CppDll.dll")]
public static extern void GetSzString(ref string rStr, int length);static void Main(string[] args)
{
string myStr = "";
GetSzString(ref myStr, 128);
Console.WriteLine("The string is {0}", myStr);Console.Read();
}
}I get the string "Hello,World" successfully. it shows on my console window.
However, my C# application crashes when it is closing.
What's wrong with my code.
What's the correct way to get a string from a C++ dll.
All Replies
-
Friday, March 16, 2012 4:31 AM
I think .NET is trying to free memory that it doesn't own, and already freed when doing execution environment tear down.
Try change the import signiture to use StringBuilder instead of ref string, the C# compiler has hardcoded to make necessary changes to the call when it sees StringBuilder as parameter.
- Edited by cheong00 Friday, March 16, 2012 4:32 AM
- Edited by cheong00 Friday, March 16, 2012 4:33 AM
- Proposed As Answer by Louis.frMicrosoft Community Contributor Friday, March 16, 2012 8:44 AM
- Unproposed As Answer by Louis.frMicrosoft Community Contributor Friday, March 16, 2012 8:45 AM
-
Friday, March 16, 2012 5:02 AM
You can try using the attribute MarshalAs
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute.aspx
If allowed please upload the dll so we can try it out here:
Resolving n Evolving in C# (http://jeanpaulva.com)
- Edited by Jean Paul V.A Friday, March 16, 2012 5:03 AM
-
Friday, March 16, 2012 6:14 AM
Hi Cheong,
I modify my C# code
===== C# application =====
[DllImport("CppExDll.dll")]
public static extern void GetSzString(StringBuilder sb, int length);static void Main(string[] args)
{
StringBuilder mySB = new StringBuilder(128);
GetSzString(mySB, 128);
Console.WriteLine("The string is {0}", mySB);Console.Read();
}It gets a empty string, the "Hello,World" doesn't show on my console window.
But, there is no crash when app is closing.
Then, I modify my code again (use ref StringBuilder instead)
===== C# application =====
[DllImport("CppExDll.dll")]
public static extern void GetSzString(ref StringBuilder sb, int length);static void Main(string[] args)
{
StringBuilder mySB = new StringBuilder(128);
GetSzString(ref mySB, 128);
Console.WriteLine("The string is {0}", mySB);Console.Read();
}It works. I get the "Hello,World" successfully and there is no crash when app is closing.
I think that it might be a correct way to get a string from C++ dll.
Thanks
- Proposed As Answer by Louis.frMicrosoft Community Contributor Friday, March 16, 2012 8:45 AM
- Marked As Answer by Neddy RenModerator Wednesday, March 28, 2012 5:54 AM
-
Friday, March 16, 2012 6:24 AM
Hi Jean,
I use the attribute MarshalAs, and I get a strange string.
(Because the UnmanagedType.LPWStr is used?)
===== C# application =====
[DllImport("CppExDll.dll")]
public static extern void GetSzString(
[MarshalAsAttribute(UnmanagedType.LPWStr)]
ref string rStr,
int length);static void Main(string[] args)
{
StringBuilder mySB = new StringBuilder(128);
GetSzString(ref mySB, 128);
Console.WriteLine("The string is {0}", mySB);Console.Read();
}And my app still crash.
By the way, I don't know how to upload my dll.
Thanks.
-
Friday, March 16, 2012 6:32 AM
Hello Lee,
You can upload the file to rapidshare/skydrive/web servers and provide the link.
But as of now you got the problem solved, I think it is not needed.
Resolving n Evolving in C# (http://jeanpaulva.com)
-
Friday, March 16, 2012 8:46 AMYou pass ref StringBuilder since the function expects a char**. Passing StringBuilder without the ref keyword would pass a char* only.
-
Friday, March 16, 2012 9:07 AMTrue. You would need to set the CharSet of the DllImport attribute. It doesn't matter anyway, since the OP is using char**.
-
Friday, March 16, 2012 10:14 AMYou're right. I've overlooked the char** here. (Not seeing your reply before decided to delete the post)

