2

I have written a C++ DLL with the following function exported

extern "C" BOOL WINAPI SetUserPassword(const char* u, const char* p)

When calling this from C# I am using the following code

[DllImport("mydll.dll")]
private static extern int SetUserPassword(String user, String password);

Now when SetUserPassword is called I only get the first letter of each parameter. I did some googling and found that String was perhaps not the best to use so tried using IntPtr and Marshal.StringToBSTR() but this didn't work either.

How should this be structured correctly? I am able to modify the C++ DLL if required.

Chris
  • 26,744
  • 48
  • 193
  • 345

1 Answers1

9

The only thing that makes sense is that your C# code is actually:

[DllImport("mydll.dll", CharSet = Unicode)]
private static extern int SetUserPassword(String user, String password);

When you do this you pass a wide character based string to your C++ code and since it expects single byte characters it interprets the 0 byte in the second half of the first two byte character as a string terminator.

You should write:

[DllImport("mydll.dll", CharSet = Ansi)]
private static extern int SetUserPassword(String user, String password);

Or in fact you could write it exactly as in your question because Ansi is the default.


And in fact it turns out that you are on CE which does not support Ansi character set and so the only reasonable solution is to make your C++ code accept wide character strings.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    Ahhh! I forgot to mention im on WinCE. All I did was change my C++ function to accept `wchar_t` and then converted that into an ANSI `std::string` and now it's all working - Thanks! – Chris Sep 02 '11 at 13:19
  • Agreed. Or [MarshalAs]. A snippet that has "mydll.dll" was not copy/pasted. Tsk, tsk, +1 for psychic debugging. – Hans Passant Sep 02 '11 at 13:24