为了账号安全,请及时绑定邮箱和手机立即绑定

为什么调用 DLL 中的函数时需要“ref”关键字?

为什么调用 DLL 中的函数时需要“ref”关键字?

C#
胡子哥哥 2023-09-16 16:19:16
我试图弄清楚为什么我需要使 DLLImport 函数的参数为“ref int XXX”,而不仅仅是“int XXX”。对于后者,这会导致“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。” 问题......但是当我将“ref”添加到参数中......它工作得很好。例如:    [DllImport("someDLL.dll", CallingConvention = CallingConvention.StdCall)]         public static extern int SomeDLL_GetDevices(ref int devices);^ 以上作品    [DllImport("someDLL.dll", CallingConvention = CallingConvention.StdCall)]         public static extern int SomeDLL_GetDevices(int devices);^ 以上崩溃和烧伤我不是从 C# 及其编组方面进行 C++ 调用的导出,因此如果有人可以解释为什么一个有效而另一个无效,我将不胜感激。
查看完整描述

1 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

上面ref int说“被调用者期望一个指向 32 位整数的指针,而编组器期望它是一个托管指针”。

指向整数的托管指针和整数是两个完全不同的东西。一种是指针大小的——通常是 64 位——另一种肯定是 32 位。一种是值,一种是描述从哪里获取包含值的变量。它们不可互换,您需要正确使用。

如果您不清楚编组层为实现这一点而使用的约定,请在编写更多编组代码之前弄清楚它。 您正在与一个不具有 C# 提供的类型安全或内存安全的系统进行交互,因此您需要确保保留运行时的不变量。通常,运行时会确保维护运行时不变量,但您正在描述如何与运行时之外的代码进行交互,因此请确保它是正确的。

尝试一些东西直到它起作用并不是一个好技巧。如果继续这样做,您可能会引入崩溃、内存泄漏和更微妙的错误(即安全漏洞)。阅读文档、书籍或视频,或者让同事向您解释,以便您了解其工作原理。然后您将能够充满信心地编写 p/invoke 代码,而不是猜测和希望。


查看完整回答
反对 回复 2023-09-16
  • 1 回答
  • 0 关注
  • 76 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信