Each time a variable is passed between managed and unmanaged code it is marshalled. AFAIK, for strings, a copy is passed, therefore the pointer to the string you are freeing will probably not be the one you allocated.
If it were my code, I'd try to keep all the memory management in C# (if at all possible).
The StringBuilder class has a different treatment under marchalling than a string in that it can be passed to unmanaged code, changed, and then returned.
Here's my ammended dll
Code:
#include <cstring>
#include <windows.h>
#define CSHARP_DLL_API extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
CSHARP_DLL_API void get_stringsafe(char *pszStr)
{
strcpy(pszStr,"Hello there");
}
And here's my C# code
Code:
using System;
using System.Text;
using System.Runtime.InteropServices;
public class MyDLL
{
[DllImport("TestCSharp.dll")]
public static extern void get_stringsafe(StringBuilder pszStr);
}
class MyMain
{
public static void Main()
{
StringBuilder oString = new StringBuilder();
oString.Capacity = 50;
MyDLL.get_stringsafe(oString);
Console.WriteLine(oString);
}
}