Передача строки из C ++ в C # - PullRequest
3 голосов
/ 16 декабря 2010

Я использую схему PInvoke, обратную PInvoke, описанную Thottam R. Sriram http://blogs.msdn.com/b/thottams/archive/2007/06/02/pinvoke-reverse-pinvoke-and-stdcall-cdecl.aspx

Кажется, все работает хорошо, за исключением передачи строки из C ++ в C.

(В Sriram строка создается в c # и передается нетронутой через c ++, поэтому проблема исключается.)

Код на C # выглядит следующим образом

class Program
{
    public delegate void callback(string str);
    public static void callee(string str)
    {
        System.Console.WriteLine("Managed: " + str);
    }

    static void Main(string[] args)
    {
        gpscom_start(new callback(Program.callee));

        Console.WriteLine("NMEA COM Monitor is running");
        System.Threading.Thread.Sleep(50000);
    }

    [DllImport("gpscomdll.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern void gpscom_start(callback call);

}

Код на C ++ выглядит следующим образом

extern "C" dllapi void __stdcall gpscom_start(void (__stdcall *callback) (BSTR str))
{

BSTR bstr = SysAllocString(L"starting monitor");
(*callback)(bstr);
SysFreeString(bstr);

При запуске все выглядит хорошо, кроме строки обратного вызова

Managed: m

Это похоже на строку UNICODE, распечатанную подпрограммой ANSI, но, конечно, строки c # являются Unicode?

TIA

Ответы [ 2 ]

4 голосов
/ 16 декабря 2010

При сортировке строк через границу P / Invoke всегда рекомендуется использовать атрибут MarshalAs с соответствующим типом строки.Я думаю, что добавление [MarshalAs(UnmanagedType.BStr)] к параметру должно решить проблему.

public delegate void callback([MarshalAs(UnmanagedType.BStr)]string str);

В этой статье есть аналогичный пример, когда кто-то передавал BSTR между управляемым и неуправляемым кодом, но он использовал IntPtr и некоторые методы в классе Marshal.Marshal.PtrToStringBSTR кажется наиболее полезным здесь.

1 голос
/ 16 декабря 2010

C # строки UTF-16.Я бы предположил, что C # может ожидать LPWSTR или нечто подобное, а не BSTR.Если вы посмотрите на первый опубликованный пример, он определяет тип вызова как wchar_t *, а не как BSTR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...