Reputation: 181
I have a native dll that I need to set a string value of a parameter. Below is the c++ method signature
__declspec(dllexport) void __stdcall getDetails(_Out_ LPTSTR lpDetails, _In_ UINT uSize)
c++ method
I've hardcoded this for the return lpDetails=L"test";
My c# signature
[return: MarshalAs(UnmanagedType.I1)]
[DllImport("test.dll",CharSet=CharSet.Auto)]
static extern bool getDetails(StringBuilder result, System.UInt32 uSize);
c# code
StringBuilder b = new StringBuilder(1000);
getDetails(b, 255);
m = b.ToString(); //always ""
Console.WriteLine(m);
When I step through the code I see the value (lpDetails) get set to the correct value. The problem is on the c# all I ever see is an empty string.
I have tried a things I found from other posts but so far no luck.
Upvotes: 0
Views: 555
Reputation: 14591
There are few things wrong here:
lpDetails=L"test"
is broken. If you provide the preallocated buffer to the function (as your signature implies) you need to _tcscpy
the details into lpDetails. If you want to allocate the string inside the function (as your implementation implies, you need to declare lpDetails as LPTSTR*
, but this is a bad design as caller might not now how to free it (and in this case indeed it cant as "test" points to a static memory in data segment and not to the heap.This wouldn't work even without Interop:
LPTSTR pCallerData; // a pointer variable
void getDetails(LPTSTR lpData, /*what do you use second param for? */)
{
// lpData is a COPY of pCallerData, not a pointer to it,
// so you are not modifying pCallerData, but a local variable
lpData = "test";
// after the function exits pCallerData still has the same value as before
}_
better implementation would be:
LPTSTR txt[256];
getDetails(txt, 256);
// ----
void getDetails(LPTSTR lpData, int size)
{
_tcscpy(lpDetails, _T("Test"));
// or more realistically _tcsncpy and properly check
// if details string is longer than size argument
}_
Upvotes: 1