将void * param传递给DLL函数时内存访问冲突

时间:2014-03-27 14:57:36

标签: c# pinvoke

我正在从我的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 *(指向空终止字符串);所以上面的driveLetter是

        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);

(我的代码几乎与代码中的代码相同:How to call SHChangeNotify from C# without error 14007 但我得到System.AccessViolationException)

有什么建议我做错了吗?

1 个答案:

答案 0 :(得分:2)

互操作签名中的第一个参数应为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);

This MSDN article显示了Win32类型与Platform Invoke的.NET类型之间的公共映射。

相关问题