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

时间:2019-08-21 22:19:18

标签: c#

我试图弄清楚为什么需要使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 个答案:

答案 0 :(得分:7)

ref int说:“被调用者期望指向32位整数的指针,而编组者期望将其作为托管指针”。

指向整数和整数的托管指针是完全不同的两件事。一个是指针大小的(通常为64位),而一个肯定是32位。一个是值,一个是对在哪里获取包含值的变量的描述。它们不可互换,您必须正确处理它们。

如果您不清楚封送处理层使用的惯例是否可以解决所有问题,请在编写更多封送处理代码之前先弄清楚它。 您所连接的系统没有C#提供的类型安全性或内存安全性,因此您需要确保保留运行时的不变性。通常,运行时可确保维护运行时不变式,但是您将描述如何与运行时中未包含的代码进行接口,因此请确保它是正确的。

尝试一些东西直到可行为止。如果继续这样做,可能会导致崩溃,内存泄漏和更多细微的错误(即安全漏洞)。阅读文档,书籍或视频,或请同事向您解释,以便您了解其工作原理。这样您就可以放心地编写p /调用代码,而不用猜测和希望了。