惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - sPhinX

如何解决在Win11下卸载McgsPro失败的问题 如何离线安装WinDbg Preview 敏捷软件开发 原则、模式与实践 第9章的例子程序(C#版) Akavache简明使用指南 Oracle存储过程解析XML内容 有意思的案例: 的问题 dnSpy - 让调试镜像文件的工作变得轻松点 dnSpy调试IIS(w3wp进程) Xilium.CefGlue与SingleProcess rocketmq-client-cpp(2.0.1)编译指南 RocketMQ .NET客户端的那些坑 P/Invoke今日谈 .NET编译问题汇总 动态的世界 使用ProcDump自动生成Dump文件 Process.Start可能无法选中指定文件的问题 获取本地IP 将exe和dll打包为一个exe文件 .NET异步资料收集
P/Invoke继续谈
sPhinX · 2020-04-25 · via 博客园 - sPhinX

上回说到封装rocketmq-client-cpp的时候会碰到内存损坏的问题,本以为能收到服务端的消息就万事大吉了,但是在深入测试的过程中,发现收到的消息会有乱码出现,

之前和服务端的研发人员讨论过字符集的问题,知道服务器回传的是UTF8的字符串,所以在接收时用下面这样的方式可以在大部分情况下得到正确的内容:

return Encoding.UTF8.GetString(Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(GetMessageIdNative(message))));

但是在少数情况下会有乱码内容,比较之后发现是中英文符号混杂的情况就会出现这种问题,经过反复测试和思考之后确认需要的是Marshal.PtrToStringUTF8,

可惜目前的项目都是在.NET Framework下开发,PtrToStringUTF8在.NET Framework中完全没有支持,所以只能自己写一个了

static string PtrToStringUTF8(IntPtr ptr)
{
    var bytesCount = 0;
    byte b;
    do
    {
        b = Marshal.ReadByte(ptr, bytesCount);
        bytesCount++;
    }
    while (b != 0);
    var bytes = new byte[bytesCount - 1];
    Marshal.Copy(ptr, bytes, 0, bytesCount - 1);
    return Encoding.UTF8.GetString(bytes);
}

没过几天,又遇到个接入某省定制多功能读卡器的需求,在这里碰到了一个看起来很简单的函数,声明如下:

long iReadXXX(char* pOutInfo)

这里的pOutInfo是一个长度为4096的输出参数,所以虽然也是要接收一个字符串,但是通过输出参数的形式,而不是上次的返回值,平台调用的形式也就必然不同。

这里采用的是接收字符数组的方式来进行调用,声明如下:

public static extern int iReadXXX(IntPtr pOutInfo);

调用代码如下:

byte[] bytes = new byte[4096];
GCHandle pinned = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var result = iReadXXX(pinned.AddrOfPinnedObject());
pinned.Free();
int count = bytes.ToList().FindIndex(b => b == 0);
var text = Encoding.Default.GetString(bytes, 0, count);