Passing string from C++ to C#

不问归期 提交于 2019-12-01 06:47:28

问题


I am using the PInvoke, reverse PInvoke scheme as described by Thottam R. Sriram http://blogs.msdn.com/b/thottams/archive/2007/06/02/pinvoke-reverse-pinvoke-and-stdcall-cdecl.aspx

Everything seems to work well, except for passing a string from C++ to C.

( In Sriram the string is constructed in c# and passed untouched through c++, so the issue is avoided. )

The c# code looks like this

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);

}

The C++ code looks like this

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

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

When run, everything looks good except the callback string

Managed: m

It looks like a UNICODE string being printed out by an ANSI routine, but surely c# strings are unicode?

TIA


回答1:


When marshalling strings across a P/Invoke boundary, it is always good practice to use a MarshalAs attribute with the appropriate string type. I think putting a [MarshalAs(UnmanagedType.BStr)] on the parameter should take care of the problem.

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

This article has an similar example where someone was passing BSTRs between managed and unmanaged code, but he used IntPtr and some methods on the Marshal class. Marshal.PtrToStringBSTR seems most useful here.




回答2:


C# strings are UTF-16. I would suggest that C# could be expecting an LPWSTR or something similar rather than a BSTR. If you look at the first example posted, he puts the call type as a wchar_t*, not a BSTR.



来源:https://stackoverflow.com/questions/4455234/passing-string-from-c-to-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!