There are several flaws as pointed out in the various replies you've got. To summarize it all, here is what I'd suggest.
On the native side, declare something like this (assuming you are coding in C++):
extern "C"
__declspec(dllexport)
const char* __cdecl Connect(const char* lpPostData)
{
static char buffer[1000];
...
return buffer;
}
The extern "C" makes it clear to the compiler that it should not mangle the function name when it gets exported, but should treat it just as it would treat a C function.
The __ceclspec(dllexport) makes the function visible in the DLL as an exported entry point. You can then reference it from outside projects.
The __cdecl ensures that you use the C way of passing arguments on the stack. You could badly mess things up if the caller does not assume the same argument passing scheme.
Use char consistently: either sick to char (ANSI text) or wchar_t (16-bit Unicode text). And never, ever, return a pointer to a local variable, as you did in your example. As soon as the function returns, that memory location won't be valid any more and could contain garbage. Furthermore, if the user is modifying the data stored there, it can cause the program to crash, because this would trash the call stack.
On the managed C# side, here is what I recommend:
[DllImport("test.dll", EntryPoint="Connect",
CharSet=CharSet.Ansi, ExactSpelling=true,
CallingConvention=CallingConvention.Cdecl)]
private static extern System.IntPtr Connect(string postData);
which will bind to your Connect entry point, use the ANSI string convention (8-bit per character, which is what char expects) and make sure the caller is expecting the __cdecl calling convetion.
You'll have to marshal the IntPtr to a string object by calling:
string value = Marshal.PtrToStringAnsi (Connect (postData));
Note: in my original post, I recommended declaring Connect as returning string, but as commenter Mattias corrected, this is not the proper way of doing it. See this article on CLR Inside Out to understand how the CLR is treating retvals of type string. Thanks for pointing this out to me (and thanks to romkyns too).
You could also consider copying the string from buffer to a piece of memory allocated through CoTaskMemAlloc in the native code, and returning a pointer to it. You could then simply declare the DllImport function as returning string and would not need to do any further marshalling in the managed world.