Ваш код неправильный на стороне C также. __в аннотации просто скажите компилятору, что вы можете изменить буфер, на который указывает аргумент "c". Но сам указатель находится в стеке и не возвращается вызывающей стороне, если вы изменили аргумент "c".
Ваша декларация может выглядеть так:
extern "C" {
TRADITIONALDLL_API int TestStrRef( __inout char** c) {
int rc = strlen(*c);
std::cout << "the input to TestStrRef is: >>" << *c << "<<" ;
*c = "This is from the C code ";
return rc;
}
}
И сторона C #:
[DllImport("MyDll.dll", SetLastError = true)]
static extern int TestStrRef(ref IntPtr c);
{
String abc = "InOut string";
IntPtr ptrOrig = Marshal.StringToHGlobalAnsi(abc)
IntPtr ptr = ptrOrig; // Because IntPtr is structure, ptr contains copy of ptrOrig
int len = TestStrRef(ref ptr);
Marshal.FreeHGlobal(ptrOrig); // You need to free memory located to abc' native copy
string newAbc = Marshal.PtrToStringAnsi(ptr);
// You cannot free memory pointed by ptr, because it pointed to literal string located in dll code.
}