【发布时间】:2011-12-21 07:14:14
【问题描述】:
我正在开发一个需要实现非托管 Windows DLL 的项目。 DLL 用于与 USB 设备进行通信。我的代码在 C# 和 WPF 中。 为了初始化 DLL,我调用了一个函数:
InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
调用此函数时,我必须传递一个名为 dllInitParams 的结构和控件绑定到的句柄。 我正在使用 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 按钮时会产生错误。 错误:
ProbeCTRL.exe 中出现“System.AccessViolationException”类型的未处理异常
附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
为什么会这样?
【问题讨论】:
-
很难说,崩溃的代码不是您发布的代码。您需要调试本机代码。项目+属性,调试选项卡,勾选“启用非托管代码调试”。在 C 或 C++ 源代码中的 InitTimerDll 函数上设置断点。
-
使用
Int32而不是IntPtr作为句柄值可能会在64 位操作系统中引起问题。您的调用约定也可能是错误的(.NET 中的默认值是 StdCall)。