我正在开发一个需要实现非托管Windows DLL的项目。 DLL用于与USB设备通信。我的代码是在C#和WPF中。 要初始化DLL,我调用一个名为:
的函数InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
调用此函数时,我必须传递一个名为dllInitParams的结构和控件绑定的Handle。 我正在使用DllImport作为函数指针:
[DllImport("myDll.dll")]
public static extern void InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
这是我的结构:
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
以上所有内容都在一个名为myDllInterface.cs的独立类中。以下是我从WPF表单中调用InitTimerDll函数的方法:
public IntPtr Handle
{
get { return (new System.Windows.Interop.WindowInteropHelper(this)).Handle; }
}
private void initTime_Click(object sender, RoutedEventArgs e)
{
myDllInterface.dllInitParams initParams = new myDllInterface.dllInitParams();
initParams.simp = 0;
myDllInterface.InitTimerDll(this.Handle.ToInt32(), ref initParams);
}
上面代码的第一部分解释了我如何获取句柄,initTime_Click显示了我如何初始化结构,通过将句柄和结构传递给它来调用initTimeDll函数。我已经在代码运行的目录中复制了dll文件。我的代码编译得很好,但是当我点击initTime按钮时会产生错误。 错误:
未处理的类型' System.AccessViolationException'发生在ProbeCTRL.exe
附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
为什么会这样?
答案 0 :(得分:1)
在不确切知道InitTimerDll()函数对'这个'指针,我会专注于params结构。尝试添加如下结构布局标记:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
另外,仔细检查您的结构是否完整和准确。
答案 1 :(得分:1)
我发现了问题。代码很好,问题是dll文件,它已损坏。 dll文件的正确副本解决了这个问题。在代码中使用dll时,确保准确的信息,函数调用,传递的数据类型等非常重要。 谢谢大家的帮助。
答案 2 :(得分:0)
查看PInvoke教程:http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx
吉姆·戈麦斯指出:[StructLayout(LayoutKind.Sequential)]
或类似的东西绝对重要。
此外,您只是初始化结构中的一个变量。