如何在 C# 中使用 Swig 包装 UTF-8 编码的 C++ std::strings?

2024-02-19

我的问题几乎相同这个问题 https://stackoverflow.com/questions/16749871/how-to-make-swig-deal-with-utf8-strings-in-c,除了链接的问题处理 char* ,而我在代码中使用 std::string 。就像链接的问题一样,我也使用 C# 作为我的目标语言。

我有一个用 C++ 编写的类:

class MyClass
{
public:
    const std::string get_value() const; // returns utf8-string
    void set_value(const std::string &value); // sets utf8-string
private:
    // ...
};

这个 get 由 SWIG 用 C# 封装,如下所示:

public class MyClass
{
    public string get_value();
    public void set_value(string value);
}

SWIG 为我做了所有事情,除了它在调用 MyClass 期间不会进行 utf8 到 utf16 字符串转换。如果我的字符串可以用 ASCII 表示,那么它们就可以很好地处理,但是如果我尝试通过“set_value”和“get_value”来回传递带有非 ASCII 字符的字符串,最终会得到难以理解的字符。

如何使 SWIG 在 C# 中包装 UTF-8 编码的 C++ 字符串?注:我使用的是 std::string,而不是 std::wstring,也不是 char*。

有一个部分解决方案SWIG sourceforge 网站 http://sourceforge.net/p/swig/patches/249/,但它处理 char* 而不是 std::string,并且它使用(可配置的)固定长度缓冲区。


在(阅读:天才!)的帮助下大卫·杰斯克 http://www.codeproject.com/Articles/138614/Advanced-Topics-in-PInvoke-String-Marshaling在链接的代码项目文章中,我终于能够回答这个问题了。

您的 C# 库中需要此类(来自 David Jeske 的代码)。

public class UTF8Marshaler : ICustomMarshaler {
    static UTF8Marshaler static_instance;

    public IntPtr MarshalManagedToNative(object managedObj) {
        if (managedObj == null)
            return IntPtr.Zero;
        if (!(managedObj is string))
            throw new MarshalDirectiveException(
                   "UTF8Marshaler must be used on a string.");

        // not null terminated
        byte[] strbuf = Encoding.UTF8.GetBytes((string)managedObj); 
        IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length + 1);
        Marshal.Copy(strbuf, 0, buffer, strbuf.Length);

        // write the terminating null
        Marshal.WriteByte(buffer + strbuf.Length, 0); 
        return buffer;
    }

    public unsafe object MarshalNativeToManaged(IntPtr pNativeData) {
        byte* walk = (byte*)pNativeData;

        // find the end of the string
        while (*walk != 0) {
            walk++;
        }
        int length = (int)(walk - (byte*)pNativeData);

        // should not be null terminated
        byte[] strbuf = new byte[length];  
        // skip the trailing null
        Marshal.Copy((IntPtr)pNativeData, strbuf, 0, length); 
        string data = Encoding.UTF8.GetString(strbuf);
        return data;
    }

    public void CleanUpNativeData(IntPtr pNativeData) {
        Marshal.FreeHGlobal(pNativeData);            
    }

    public void CleanUpManagedData(object managedObj) {
    }

    public int GetNativeDataSize() {
        return -1;
    }

    public static ICustomMarshaler GetInstance(string cookie) {
        if (static_instance == null) {
            return static_instance = new UTF8Marshaler();
        }
        return static_instance;
    }
}

然后,在 Swig 的“std_string.i”中,第 24 行替换这一行:

%typemap(imtype) string "string"

用这一行:

%typemap(imtype, inattributes="[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]", outattributes="[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]") string "string"

在第 61 行,替换这一行:

%typemap(imtype) const string & "string"

用这一行:

%typemap(imtype, inattributes="[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]", outattributes="[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]") string & "string"

你瞧,一切正常。阅读链接的文章以更好地了解其工作原理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C# 中使用 Swig 包装 UTF-8 编码的 C++ std::strings? 的相关文章

  • 为 DocumentDb 设置自定义 json 转换器

    我正在使用类型化 DocumentQuery 从 Azure DocumentDb 集合中读取文档 from f in client CreateDocumentQuery
  • EF Core 返回 null 关系,直到直接访问

    我有一些如下所示的模型 public class Mutant public long Id get set Relations public long OriginalCodeId get set public virtual Origi
  • 如何使用C从http下载文件?

    最近几天我试图弄清楚如何从 URL 下载文件 这是我对套接字的第一个挑战 我用它来了解协议 所以我想在没有 cURL 库的情况下只用 C 语言来完成它 我搜索了很多 现在我可以打印页面的源代码 但我认为这与文件不同 我不必只将接收到的数据从
  • 带有 ASP.NET 按钮回发的 jQuery UI 对话框

    我的 ASP NET 页面上有一个运行良好的 jQuery UI 对话框 jQuery function jQuery dialog dialog draggable true resizable true show Transfer hi
  • 如何使用不同的基本路径托管 Blazor WebAssembly 应用程序

    我有一个 Blazor Webassemble NET 托管应用程序 在我们托管它的服务器上 应用程序的基本路径将是mydomain com coolapp 因此 为了尝试让应用程序在服务器上正确呈现 我一直遵循本页 应用程序基本路径 部分
  • 未找到 DEADLINE 调度策略

    我想在 C 中实现 DEADLINE 调度策略 我知道该功能已实现Linux 3 14 10我正在使用 Ubuntu 14 04Linux 3 17 0 031700 lowlatency 201410060605 SMP PREEMPT这
  • 来自 double 的 static_cast 可以优化分配给 double 吗?

    我偶然发现了一个我认为不必要的功能 并且通常让我感到害怕 float coerceToFloat double x volatile float y static cast
  • 如何使用T4从一个模板同时生成两个文件?

    我遇到的情况是 我需要生成两个 CSharp 代码文件 它们的代码几乎相同 但方法的输入和输出类型的命名空间不同 事实上 每个文件都针对特定国家 地区 并且类型来自特定国家 地区的 WSDL 我正在围绕服务编写一些包装器 逻辑完全相同 但从
  • 如何在 C++ 中为指针“this”赋值

    在函数中 如何分配this一个新的价值 您可以分配对象this点于 this XY 但你不能分配直接值this this XY Error Expression is not assignable
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • 加载 QPixmap 数据的更好方法

    更好的方法来做到这一点 没有QImage QImage image width height QImage Format RGB888 memcpy image bits m frameRGB gt data 0 height width
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • MPI - 发送和接收列

    我需要从一个进程发送矩阵列并从另一个进程接收它 我尝试运行以下程序 但得到了一个奇怪的结果 至少我这么认为 仅复制矩阵的第一个元素 某些矩阵元素会发生意外变化 include
  • 具有多个父项的 Qt 树模型

    我想构建一棵树 其中一个元素可以引用另一个元素 我想要构建的树是 像这样的东西 A B C D E F P this is a pointer to C D first child of C E second child of C I fo
  • 在一个解决方案中调用不同项目的方法

    1 个解决方案中有 3 个项目 我对第一个项目中的主文件进行的主要操作 但是我需要调用第三个项目中的方法并使用类 例如 第三个项目有 public DataClasses1DataContext base global WindowsFor
  • 如何防止 Lotus Notes 用户转发或复制通过 System.Net.Mail 发送的邮件?

    我想使用 SMTP 客户端 uiing microsft net 以 C 作为编程语言发送电子邮件 但是对于通过SMTP客户端发送的电子邮件 我们是否可以添加 禁止转发 或 禁止复制 等安全功能 我不希望电子邮件的收件人转发或复制电子邮件的
  • 异步/等待 - 是*并发*吗?

    我一直在考虑 C 5 中新的异步内容 并且出现了一个特殊问题 据我了解 await关键字是一个简洁的编译器技巧 语法糖来实现连续传递 http en wikipedia org wiki Continuation passing style
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • 稀疏矩阵超定线性方程组c/c++库

    我需要一个库来解决 Ax b 系统 其中 A 是一个非对称稀疏矩阵 每行有 8 个条目 而且可能很大 我认为实现双共轭梯度的库应该没问题 但我找不到一个有效的库 我尝试过 iml 但 iml sparselib 包中缺少一些标头 有小费吗
  • 如何将模型绑定到动态创建的类 nancyfx

    首先感谢任何愿意查看我的问题的人 我对 Nancyfx 还很陌生 在尝试将 JSON 有效负载绑定到动态创建的类时遇到问题 我按照这篇文章中的代码动态创建了该类 在C 中动态创建一个类 https stackoverflow com que

随机推荐