从C#WPF应用程序调用非托管Windows DLL时出错

时间:2011-12-12 18:44:37

标签: c# .net wpf pinvoke

我正在开发一个需要实现非托管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

     

附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

为什么会这样?

3 个答案:

答案 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)]

或类似的东西绝对重要。

此外,您只是初始化结构中的一个变量。