c# – 为什么编组对象不保留在本机代码中修改的值?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 为什么编组对象不保留在本机代码中修改的值?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1950字,纯文字阅读大概需要3分钟。
内容图文
我确信有一个简单的答案,但经过一些研究后我找不到它.我阅读并证明(除非我写的是错误的)自动编组通过托管内存中分配的引用(或类)传递的结构,由本机代码正确读取和写入,但是一旦代码执行返回到托管层,不保留本机代码中更改的值.这是一个例子:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class DirtyWordsCheckResult
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
public string replace_string;
public EnumDirtyWordsType dirty_type;
public DirtyWordsCheckResult()
{
replace_string = new string(' ', 1024);
}
}
public enum EnumDirtyWordsType
{
kDirtyWordsTypeNormalAllowWords = 0, // normal allow words
kDirtyWordsTypeEvil = 1, // illegal,can not be displayed
kDirtyWordsTypeSensitive = 2, // legal, but contain sensitive
}
public override EResult DirtyWordsFilter(string words, bool replace_sensitive, out DirtyWordsCheckResult check_result)
{
check_result = new DirtyWordsCheckResult();
var result = Utils.DirtyWordsFilter(utils_, words, replace_sensitive, check_result);
return result;
}
本机函数DirtyWordsFilter确实正确地获取了已分配的对象,并且可以在其中写入而没有问题,但是不保留这些值.
现在我知道我可以使用Marshal.AllocHGlobal来传递预分配的IntPTR,因此我不是在寻找解决方案,我只是想知道为什么原始机制不起作用.
解决方法:
你使用的结构不是blittable.一个昂贵的单词意味着本机布局与托管布局不同.字符串导致它.不仅仅因为CharSet,.NET字符串看起来不像char [].这需要pinvoke编组程序在传递本机代码可以使用的指针之前创建正确大小的副本.
但它默认情况下不会复制修改过的struct.你必须在参数上放置[Out]以改变它的想法.我们看不到[DllImport]声明,但它应该类似于:
[DllImport(...)]
private static extern EResult DirtyWordsFilter(..., [Out] DirtyWordsCheckResult check_result);
pinvoke marshaller对数据流没有特定的了解,即使你在声明中使用ref或out(通常存在于struct声明中)也没有.它只是看到参数通过引用传递,并假设[In]为默认值.通常是正确和最佳的猜测,而不是这里. Fwiw,请注意Pack = 1几乎永远不会正确,它需要匹配本机代码中使用的打包,它的默认值也是8.在这个特定情况下发生无关紧要.
内容总结
以上是互联网集市为您收集整理的c# – 为什么编组对象不保留在本机代码中修改的值?全部内容,希望文章能够帮你解决c# – 为什么编组对象不保留在本机代码中修改的值?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。