0

I'm trying to use P/Invoke to call functions in an unmanaged C++ DLL from C#. The C++ DLL uses CString's as function parameters and returns, such as

CString AFX_EXT_API GetUserName(CString& userID)

Unfortunately, the C++ is legacy code that I cannot change to use the more universal LPSTR (or even char *).

Is there any way to marshal the CString into a .NET compatible object? Or somehow decorate a .NET char[] to be marshaled to a CString?

johnluetke
  • 3,393
  • 1
  • 20
  • 25

2 Answers2

3

You can't create a CString in managed code. So clearly you need an extra layer between the managed code and the native code.

This gives you an opportunity to make a C++/CLI DLL which sits between. You can call this code from your managed assembly without needing P/invoke. And from the C++/CLI middle layer you can create a CString.

However, there is one caveat. You must be using the same C++ runtime as the native DLL. This may be possible but it is quite likely that it will be a stumbling block. For example if the DLL was written with MSVC6 then you will need to build your intermediate layer with MSVC6 too and that rules out C++/CLI. Back to P/invoke and char* in that case.

I would stress that it is terrible practice to export a DLL interface based on CString and I'd be looking for alternatives to the DLL.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • The DLL contains critical business logic that would take a much longer time to convert to .NET. I agree that it was a bad idea to export DLL functions with a CString in the first place, but the legacy code was written 15 years ago. It definitely puts future-proofing into perspective. – johnluetke Oct 01 '11 at 21:43
1

If you can't change the DLL itself, the obvious choice is writing a proxy DLL which would accept char[], allocate a CString and then call the DLL.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121