ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-将字符缓冲区从.NET传递到COM并重新更新

2019-10-29 10:08:26  阅读:148  来源: 互联网

标签:com com-interop c net


我有以下从C#调用的COM方法,该方法在提供的缓冲区pchText中返回一个字符串(不一定以零结尾),并在pcch中复制字符数:

HRESULT Next([in, out] long* pcch, [out, size_is(*pcch)] OLECHAR* pchText);

如何为互操作定义C#签名?

到目前为止,我已经尝试过了:

void Next(ref int pcch,
    [MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 0)]
    System.Text.StringBuilder pchText);

它似乎可以工作,但是我不确定SizeParamIndex是否对StringBuilder有影响.

解决方法:

好吧,正确调用当然是一个困难的函数.您的声明大致上是可以的,您只需要应用[PreserveSig]属性并将返回值类型设置为int,就可以发现一个S_FALSE返回值,该值指示没有下一个元素.

困难在于必须预先猜测要传递多少StringBuilder.本机代码获取指向GC堆的原始指针,指向构建器缓冲区,因此事故非常致命.您必须预先猜测构建器的适当容量,并将其作为初始pcch参数传递.

函数返回后,编组器确实注意SizeParamIndex.它将仅复制ppch指示的字符.如果由于某种原因写入的内容超出了缓冲区的容量,则该程序将立即终止,并显示ExecutionEngineException,因为这表明GC堆已损坏.

请注意,如果您猜测容量太低,则不一定能发现这一点.当函数仅复制适合的多个字符且不返回错误代码时,您可能会得到截断的字符串.找出是否存在问题的最佳方法是仅对其进行测试并有意通过一个小型构建器.注意返回值.

值得一提的是,该功能签名击中了COM早期的一种常见攻击,实际上是通过OLECHAR *返回二进制数据而不是文本.有一个很强的提示,因为不能保证该字符串以零结尾.在.NET中,这并不能很好地完成,当对字符串进行规范化时,数据将被破坏.当数据碰巧匹配utf-16代理字符之一时,使程序崩溃.如果是这种情况,则需要short []而不是StringBuilder.

标签:com,com-interop,c,net
来源: https://codeday.me/bug/20191029/1958959.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有