从C ++字符串传递到C# [英] Passing string from C++ to C#

查看:286
本文介绍了从C ++字符串传递到C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用的PInvoke,反向PInvoke的方案由Thottam R.斯利拉姆的 http://blogs.msdn.com/b/thottams/archive/2007/06/02/pinvoke-reverse-pinvoke-and-stdcall-cdecl。 ASPX



一切似乎运作良好,除了从C ++传递一个字符串到C



>(在斯利拉姆字符串是在C#构造,并通过C ++不变,因此避免了这个问题。)

C#代码看起来像这样

 类节目
{
公众委托无效回调(字符串str);
公共静态无效的被叫方(字符串str)
{
的System.Console.WriteLine(管理:+ STR);
}

静态无效的主要(字串[] args)
{
gpscom_start(新的回调(Program.callee));

Console.WriteLine(NMEA COM监视器运行);
System.Threading.Thread.Sleep(50000);
}

函数[DllImport(gpscomdll.dll,CallingConvention = CallingConvention.StdCall)]
公共静态外部无效gpscom_start(回拨电话);

}



C ++代码看起来像这样

 的externCdllapi无效__stdcall gpscom_start(无效(__stdcall *回调)(BSTR STR))
{

BSTR BSTR = SysAllocString(L开始监视);
(*回调)(BSTR);
SysFreeString(BSTR);

在运行时,一切看起来除了回调字符串


$ B $好b

 管理​​:M 

它看起来像一个UNICODE正在打印串出由ANSI常规,但肯定C#字符串都是Unicode?

TIA


解决方案

在整个在P编组串/ Invoke的边界,它总是使用的MarshalAs 属性与相应的字符串类型很好的做法。我觉得把一个 [的MarshalAs(UnmanagedType.BStr)] 的参数应采取照顾的问题。

 公共委托无效回调([的MarshalAs(UnmanagedType.BStr)字符串str); 

这篇文章具有其中有人通过托管和非托管代码之间的BSTRs类似的例子,但他用的IntPtr 和Marshal类中的一些方法。 Marshal.PtrToStringBSTR 似乎是最有用的在这里。


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

解决方案

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.

这篇关于从C ++字符串传递到C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆