C#WPF将UTF16字符串传递给接受char *的函数*

问题描述 投票:1回答:1

我创建了一个wpf项目,该项目具有一个包含所有我的c ++后端代码的辅助静态类。一种这样的函数定义为:

public static unsafe class Backend {

    [DllImport("Mandel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public extern static void write(void* ptr, char* path);
}
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            string path = "mypath";
            InitializeComponent();
            unsafe
            {
                char *p; //convert
                void* myObj = Backend.init_obj(1920, 1080);
                Backend.gen(myObj);
                Backend.write(myObj, p);
            }
        }
    }

void* ptr实际上是我的对象,为了将其编组到C#端而被强制转换。我面临的问题是,每当我尝试使用wpf中的字符串文字调用此函数时,我都会发现Visual C#无法转换此字符串,因为字符串文字是以UTF16编码的。自然,除了手动将相关字节复制到char数组外,我还尝试了其他许多事情。有提示吗?

c# wpf pinvoke
1个回答
1
投票

CLR可以很好地与C / C ++代码互操作,其中之一就是在托管和非托管代码之间编排数据结构。由于字符串非常重要,因此使字符串尽可能地具有元帅化的工作很多。

作为旁注,您将void*用于由init创建并传递给write的上下文对象。由于您只是将其交还,因此可以将其替换为IntPtr,并完全避免使用unsafe块。 IntPtr始终是当前体系结构中指针的大小。

首先,让我们更改导入函数的声明。 CharSet.Ansi告诉它以ANSI封送字符串。 ptr参数变为IntPtr

[DllImport("Mandel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public extern static IntPtr init(int width, int height);

[DllImport("Mandel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public extern static void gen(IntPtr ptr);

[DllImport("Mandel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public extern static void write(IntPtr ptr, string path);

从那里,您可以弄清楚如何修改该函数以取消分配ptr和您必须调用的其他任何函数。

使用这些功能变得更加容易和整洁。您不需要unsafe块,可以将path直接传递给write

public MainWindow()
{
    string path = "mypath";
    InitializeComponent();

    IntPtr myObj = Backend.init_obj(1920, 1080);
    Backend.gen(myObj);
    Backend.write(myObj, path);
}

使它起作用的原始注释:

而不是尝试自己创建char*参数,而是更改声明,使第二个参数为string,然后由运行时为您编组它。因为它是ANSI字符串,所以您永远不会获得完全的Unicode保真度,但这是C ++代码创建的问题。

© www.soinside.com 2019 - 2024. All rights reserved.