C#调用参数为函数指针的API函数 - 以SetUnhandledExceptionFilter为例编写一个全局异常处理程序
C#中如果要调用API函数,首先要声明使用下面这个名字空间,否则无法调用API函数: using System.Runtime.InteropServices;
其次,声明导入库和导入函数,在这里用一个写INI文件的API函数举例如下:
[DllImport("kernel32")] private static extern long WritePrivateProfileString(string section, string key,string val,string filePath);
要调用SetUnhandledExceptionFilter,问题还不仅仅是调API那么简单,还牵涉到怎么把一个C#函数做为函数指针传递给API函数,C#的标准方法是使用代理来作为函数指针,例如代理可以这样声明:
public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam) ;
我通过做实验写了一个C#小程序,粗略的实现了一个全局异常截获程序,程序还有一些问题,不够完善,程序中是用rtlmovememory函数来人
为的制造了一个全局异常,最后一个参数选200就是为了输入一个非法参数,在我的电脑上正好可以引发异常,如果在您的电脑上无法引发异常,可以调整这个参
数试试。 全部代码如下: form1.cs --------------------------------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices;
namespace SetUnhandledExceptionFilter { public partial class Form1 : Form {
public delegate Int32 CallBack(ref long a); CallBack mycall;
[DllImport("kernel32")] private static extern void RtlMoveMemory(ref byte dst, ref byte src, Int32 len);
[DllImport("kernel32")] private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);
public static Int32 newexceptionfilter(ref long a) { MessageBox.Show("截获了全局异常!"); return 0; }
public Form1() { InitializeComponent();
mycall = new CallBack(newexceptionfilter); SetUnhandledExceptionFilter(mycall);
}
private void button1_Click(object sender, EventArgs e) { byte a=1, b=2; MessageBox.Show("a=" + a.ToString()); RtlMoveMemory(ref a, ref b, 200); MessageBox.Show ("a=" + a.ToString()); } } } ---------------------------------------------------------------------
|