向DLL函数传递void*参数时内存访问冲突

本文关键字:参数 内存 访问冲突 void DLL 函数 | 更新日期: 2023-09-27 17:53:57

我要从我的c#代码中添加新的磁盘设备到系统中,所以我想调用

[System.Runtime.InteropServices.DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static void SHChangeNotify(long wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
象下面这样

MyWin32Functions.SHChangeNotify(0x00000100/*ADDRIVE*/, 0x0005/*PATHW*/, driveLetter, IntPtr.Zero); 

dwItem1是void*,我们应该传递一个wchar_t*(指向空终止字符串),在这种情况下包含驱动器根;所以上面的驱动器是

        string letter = "Z:''";
        byte[] data = Encoding.Default.GetBytes(letter);
        byte[] zdata = new byte[data.Length + 1];
        data.CopyTo(zdata, 0);
        IntPtr p = System.Runtime.InteropServices.Marshal.AllocHGlobal(zdata.Length);
        System.Runtime.InteropServices.Marshal.Copy(zdata, 0, p, zdata.Length);

(我的代码几乎与类似情况下的代码相同:如何从c#调用SHChangeNotify而不会出错14007但是我得到System.AccessViolationException)

有什么建议我做错了吗?

向DLL函数传递void*参数时内存访问冲突

互操作签名中的第一个参数应该是int,而不是long。虽然Win32函数声明为LONG,但Win32中的LONG是32位的。

[System.Runtime.InteropServices.DllImport("Shell32.dll")]
public extern static void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

这篇MSDN文章展示了用于平台调用的Win32类型和。net类型之间的公共映射。