我试图弄清楚为什么需要使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 ++调用中进行导出的,而是将其编组在一起,因此,如果有人可以解释为什么一个有效而一个无效的原因,我将不胜感激。
答案 0 :(得分:7)
ref int
说:“被调用者期望指向32位整数的指针,而编组者期望将其作为托管指针”。
指向整数和整数的托管指针是完全不同的两件事。一个是指针大小的(通常为64位),而一个肯定是32位。一个是值,一个是对在哪里获取包含值的变量的描述。它们不可互换,您必须正确处理它们。
如果您不清楚封送处理层使用的惯例是否可以解决所有问题,请在编写更多封送处理代码之前先弄清楚它。 您所连接的系统没有C#提供的类型安全性或内存安全性,因此您需要确保保留运行时的不变性。通常,运行时可确保维护运行时不变式,但是您将描述如何与运行时中未包含的代码进行接口,因此请确保它是正确的。
尝试一些东西直到可行为止。如果继续这样做,可能会导致崩溃,内存泄漏和更多细微的错误(即安全漏洞)。阅读文档,书籍或视频,或请同事向您解释,以便您了解其工作原理。这样您就可以放心地编写p /调用代码,而不用猜测和希望了。