data type in pInvoke?

J

Jeff A

I am trying to use pInvoke and I need to pass some data from a C++ dll
to C# app and vice-a-versa.

The data which needs to be passed to C# app is WCHAR* in the dll. How do
I marshal them? Do I need to allocate memory to the string in the dll?

I used this in the DLL
void GetMsg(LPTSTR msg)
{
wcsncpy(msg,lpszTheData,256);
}
and this in C# app

[DllImport("MyDll.dll")]
public static extern int GetMsg([MarshalAs(UnmanagedType.LPStr)]
ref string msg);

static void Main(string[] args)
{
string msg="Hello from .NET";
try
{
GetMsg(ref msg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine(msg);//this gives exception saying msg is
null
Console.ReadKey();
}

I also tried without the ref keyword and tried UnmanagedType.LPTStr &
UnmanagedType.LPWStr but none is working.

Please help.

Thanks & Regards,
Jeff
 
T

Tim Jarvis

Jeff said:
I am trying to use pInvoke and I need to pass some data from a C++
dll to C# app and vice-a-versa.

The data which needs to be passed to C# app is WCHAR* in the dll. How
do I marshal them? Do I need to allocate memory to the string in the
dll?

I used this in the DLL
void GetMsg(LPTSTR msg)
{
wcsncpy(msg,lpszTheData,256);
}
and this in C# app

[DllImport("MyDll.dll")]
public static extern int
GetMsg([MarshalAs(UnmanagedType.LPStr)] ref string msg);

static void Main(string[] args)
{
string msg="Hello from .NET";
try
{
GetMsg(ref msg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine(msg);//this gives exception saying msg
is null Console.ReadKey();
}

I also tried without the ref keyword and tried UnmanagedType.LPTStr &
UnmanagedType.LPWStr but none is working.

Please help.

Thanks & Regards,
Jeff

Hi Jeff,

if you marshal your string as a lpstr you won't need the ref keyword,
the interop services will handle that for you. Have you looked at your
calling conventions? Visual C++ by default uses cdecl IIRC and the
interop system will assume stdcall (WinAPI) by default I think.

Regards Tim.

--
 
A

Ashutosh Bhawasinka

For pInvoke don't marshall your string as LPStr, its for char*.
Since you are using WCHAR*, use LPTStr or LPWStr, also don't pass the
strings as ref.

something like this,
public static extern int
GetMsg([MarshalAs(UnmanagedType.LPTStr)]string msg);

Now, one thing you need to take care is the size of the string.

if you just do this
string s1;
GetMsg(s1);

you won't get anything from the dll.

The string you pass should be long enough to hold the data you will be
passing back.
So, use something like this,
String s1 = new String('\0',512);
GetMsg(s1);

Secondly, in the C++ dll, you can't assign memory to the string/pointer
like this

void GetMsg(LPTSTR msg)
{
msg = new WCHAR[1024]; //this will compile fine, but your data won't be
passed to the calling .net application.
}

MSFT GUY, please correct me if I am wrong!!

Regards,
Ashutosh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top