I've been using P/Invoke for a long time now, but there is one thing i never quite managed to do. Sending a unicode string from C# to C++.
That is given a small test CPP library like this:
CODE
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) void PrintString(const char* string)
{
cout << string << endl;
}
extern "C" __declspec(dllexport) void PrintStringW(const wchar_t* string)
{
wcout << string << endl;
}
And corresponding C# test program like this
CODE
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace CSConsole
{
class Program
{
[DllImport("CPPLibrary", EntryPoint = "PrintString")]
public static extern void PrintStringIntern(string toPrint);
[DllImport("CPPLibrary", EntryPoint = "PrintStringW")]
public static extern void PrintStringInternPtr(IntPtr toPrint);
[DllImport("CPPLibrary", EntryPoint = "PrintString", CharSet=CharSet.Ansi)]
public static extern void PrintStringInternA(string toPrint);
[DllImport("CPPLibrary", EntryPoint = "PrintStringW", CharSet = CharSet.Unicode)]
public static extern void PrintStringInternW([MarshalAs(UnmanagedType.LPWStr)]string toPrint);
static void Main(string[] args)
{
// make sure we can see unicode characters
Console.OutputEncoding = System.Text.Encoding.UTF8;
// hello world should pass just fine ... and it does
PrintString("Hello World.");
// this time i would very much like to see a copyright sign (c),
PrintString("Hello World. " + '\u00A9' + " (unicode)");
// and finally how about a e' ...
PrintString("Hello World. " + '\u00E9' + " (unicode)");
Console.WriteLine(Environment.NewLine + "(any key to continue)");
Console.ReadKey();
}
static void PrintString(string toPrint)
{
toPrint = toPrint.Normalize(NormalizationForm.FormKC);
Console.WriteLine("C#:\t\t" + toPrint);
Console.Write("C++:\t\t");
PrintStringIntern(toPrint);
Console.Write("C++ (ansi):\t");
PrintStringInternA(toPrint);
Console.Write("C++ (uni):\t");
PrintStringInternW(toPrint);
Console.Write("C++ (ptr):\t");
IntPtr pointer = Marshal.StringToHGlobalUni(toPrint);
PrintStringInternPtr(pointer);
Console.WriteLine();
}
}
}
I would very much like to see the same unicode string in C# and C++.
Oh ... the output for the above is actually:
CODE
C#: Hello World.
C++: Hello World.
C++ (ansi): Hello World.
C++ (uni): Hello World.
C++ (ptr): Hello World.
C#: Hello World. © (unicode)
C++: Hello World. � (unicode)
C++ (ansi): Hello World. � (unicode)
C++ (uni): Hello World. � (unicode)
C++ (ptr): Hello World. � (unicode)
C#: Hello World. é (unicode)
C++: Hello World. � (unicode)
C++ (ansi): Hello World. � (unicode)
C++ (uni): Hello World. � (unicode)
C++ (ptr): Hello World. � (unicode)
(any key to continue)
I hope someone here can help. Thanks
Frank