gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 15:28:47 24 4
gpt4 key购买 nike

我有以下要从 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 有多大。 native 代码获取一个指向 GC 堆的原始指针,指向构建器缓冲区,因此发生事故是非常致命的。您必须预先为构建器猜测合适的容量并将其作为初始 pcch 参数传递。

编码器确实在函数返回后注意 SizeParamIndex。它只会复制 ppch 指示的字符数。如果它出于任何原因写入的内容超出了缓冲区的容量,那么程序将立即中止并抛出 ExecutionEngineException,因为这表明 GC 堆已损坏。

请注意,如果您猜测的容量太低,那么您不一定能发现这一点。当函数只复制适合的字符并且不返回错误代码时,您可能只会得到一个截断的字符串。找出这是否是一个问题的最佳方法是通过测试它并故意通过一个小型构建器。注意返回值。

有一个怪癖值得指出,函数签名攻击了 COM 早期常见的黑客攻击,实际上通过 OLECHAR* 返回二进制数据而不是文本。强烈暗示情况就是如此,因为不能保证字符串以零结尾。这在 .NET 中不会有好结果,当字符串规范化时数据会损坏。当数据恰好与 utf-16 代理字符之一匹配时,程序会崩溃。如果是这种情况,那么您需要一个 short[] 而不是 StringBuilder。

关于c# - 将字符缓冲区从 .NET 传递到 COM 并更新它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24980511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com