Marshal UTF8 Strings in .NET

原文:Marshal UTF8 Strings in .NET

Marshal UTF8 Strings in .NET

Wow, what a pain in the butt. .NET strings are stored internally as UTF16, not UTF8, so if you‘re marshaling strings to and from a library that wants strings as UTF8, you have to manually
marshal them yourself.

This took me a whole day to figure out why my my .NET wrapper library wasn‘t working, and a whole other day to figure out how to work around it and debug the code. If this code saves at least one person the amount of time I lost then I‘m satisfied.

        public class MarshalPtrToUtf8 : ICustomMarshaler
        {
            static MarshalPtrToUtf8 marshaler = new MarshalPtrToUtf8();

            public void CleanUpManagedData(object ManagedObj)
            {

            }

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

            public int GetNativeDataSize()
            {
                return Marshal.SizeOf(typeof(byte));
            }

            public int GetNativeDataSize(IntPtr ptr)
            {
                int size = 0;
                for (size = 0; Marshal.ReadByte(ptr, size) > 0; size++)
                    ;
                return size;
            }

            public IntPtr MarshalManagedToNative(object ManagedObj)
            {
                if (ManagedObj == null)
                    return IntPtr.Zero;
                if (ManagedObj.GetType() != typeof(string))
                    throw new ArgumentException("ManagedObj", "Can only marshal type of System.String");
                byte[] array = Encoding.UTF8.GetBytes((string)ManagedObj);
                int size = Marshal.SizeOf(array[0]) * array.Length + Marshal.SizeOf(array[0]);
                IntPtr ptr = Marshal.AllocHGlobal(size);
                Marshal.Copy(array, 0, ptr, array.Length);
                Marshal.WriteByte(ptr, size - 1, 0);
                return ptr;
            }

            public object MarshalNativeToManaged(IntPtr pNativeData)
            {
                if (pNativeData == IntPtr.Zero)
                    return null;
                int size = GetNativeDataSize(pNativeData);
                byte[] array = new byte[size - 1];
                Marshal.Copy(pNativeData, array, 0, size - 1);
                return Encoding.UTF8.GetString(array);
            }

            public static ICustomMarshaler GetInstance(string cookie)
            {
                return marshaler;
            }
        }

You‘ll notice that there‘s a lot of data copying going on and there are a few copies of string made. Yep, that‘s because the .NET framework can‘t just pin the array in memory that stores the string (remember, strings are stored as UTF16 in the .NET framework)
and you have to make the conversion yourself.

时间: 2024-08-28 17:11:59

Marshal UTF8 Strings in .NET的相关文章

PHP 与 UTF-8

没有一行式解决方案.小心.注意细节,以及一致性. PHP 中的 UTF-8 糟透了.原谅我的用词. 目前 PHP 在低层次上还不支持 Unicode.有几种方式可以确保 UTF-8 字符串能够被正确处理, 但并不容易,需要深入到 web 应用的所有层面,从 HTML,到 SQL,到 PHP.我们旨在提供一个简洁. 实用的概述. PHP 层面的 UTF-8 基本的字符串操作,如串接 两个字符串.将字符串赋给变量,并不需要任何针对 UTF-8 的特殊东西. 然而,多数 字符串函数,如 strpos(

About using UTF-8 fields in MySQL

https://www.adayinthelifeof.nl/2010/12/04/about-using-utf-8-fields-in-mysql/ I sometimes hear: “make everything utf-8 in your database, and all will be fine”. This so-called advice could not be further from the truth. Indeed, it will take care of int

utf8 string

https://github.com/BassLC/idUTF8lib Idiot's UTF-8 Library A very (too much really) simple Utf8 library for C++ Usage #include "lib/idutf8lib.hpp" Utf8String text; //Empty UTF8 object Utf8String utf8_text("Hé??ò ?órld"); //std::string c

有道词典中的OCR功能:第三方库的变化

之前有点好奇有道词典中的OCR功能,具体来说就是强力取词功能.我知道的最有名的OCR库是tesseract,这个库是惠普在早些年前开源的. 在用python做爬虫处理验证码的时候,就会用到这个库,对应的python封装版本名字叫pytesseract.在github上可以找到tesseract的源码. 不过,此前在有道词典安装之后的文件夹中,我并未找到tesseract库.直到最近,更新了有道词典,换了新版本,才意外在文件下找到一个名叫tessdll.dll的文件. 与此同时,我对照了一下旧版本

正则表达式及R字符串处理之终结版

转载于: 正则表达式及R字符串处理之终结版 0.动机:为什么学习字符串处理 传统的统计学教育几乎没有告诉过我们,如何进行文本的统计建模分析.然而,我们日常生活中接触到的大部分数据都是以文本的形式存在.文本分析与挖掘在业界中也有着非常广泛的应用. 由于文本数据大多属于非结构化的数据,要想对文本数据进行传统的统计模型分析,必须要经过层层的数据清洗与整理. 今天我们要介绍的『正则表达式及R字符串处理』就是用来干这一种脏活累活的. 与建立酷炫的模型比起来,数据的清洗与整理似乎是一种低档次的工作.如果把建

C++ supports various string and character types,

String and Character Literals (C++) Visual Studio 2015 Other Versions C++ supports various string and character types, and provides ways to express literal values of each of these types. In your source code, you express the content of your character

php之道

PHP The Right Way. Tweet 欢迎 目前网络上充斥着大量的过时资讯,让 PHP 新手误入歧途,并且传播着错误的实践以及不安全的代码.PHP 之道 收集了现有的 PHP 最佳实践.编码规范和权威学习指南,方便 PHP 开发者阅读和查找 使用 PHP 沒有规范化的方式.本网站主要是向 PHP 新手介绍一些他们没有发现或者是太晚发现的主题, 或是经验丰富的专业人士已经实践已久的做法提供一些新想法.本网站也不会告诉您应该使用什么样的工具,而是提供多种选择的建议,并尽可能地说明方法及用

优秀的PHP开源项目集合

包管理Package Management Libraries for package and dependency management. Composer/Packagist– A package and dependency manager. Composer Installers– A multi framework Composer library installer. Package Management Related Libraries related to package ma

awesome-php中英文资源整理(同步更新)

中文版 收集整理一些常用的PHP类库, 资源以及技巧. 以便在工作中迅速的查找所需… 这个列表中的内容有来自 awesome-php 的翻译, 有来自开发者周刊以及个人的积累等. 一个前端组件的列表 awesome-frontend 推荐 学习资源 PHP相关的有参考价值的社区,博客,网站,文章,书籍,视频等资源 PHP网站(PHP Websites) PHP The Right Way – 一个PHP实践的快速参考指导 PHP Best Practices – 一个PHP最佳实践 PHP We