1, PInvoke什么意思? Platform Invocation Services


2, 干什么用?  导入外部函数?什么是外部函数,就是不属于.Net托管的函数。


3,如何用?看下面的例子。用[DllImport(dllname)]来实现,但是首先要把System.Runtiime.InteropServices using进来。但是不using也行,就要敲全称,随你便了。

C#通过p/invoke调用C++ DLL (转)_.net[DllImport("user32.dll")]

C#通过p/invoke调用C++ DLL (转)_.net static extern int MessageBoxA(int hWnd,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string msg,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string caption,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net int type );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net private void button1_Click(object sender, System.EventArgs e)

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 MessageBoxA( 0, "Msg:hello", "Caption:Hello",0 );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18 }

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net


4,万一我的程序中已经有了一个函数叫MessageBoxA怎么办?这时候,可以使用EntryPoint来帮忙,下面的例子中,你把自己的函数定义为MyMsg.

C#通过p/invoke调用C++ DLL (转)_.net[DllImport("user32.dll",EntryPoint="MessageBoxA")]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static extern int MyMsg(int hWnd,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string msg,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string caption,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net int type );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net private void button1_Click(object sender, System.EventArgs e)

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 MyMsg( 0, "Msg:hello", "Caption:Hello",0 );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18 }

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net


5,charset如何使用?****A的是Ansi编码,****W的是unicode编码,如何使用charset,看你的函数调用而定。2K以后都用unicode了,前面的9x都是ansi编码,但是这是缺省的,微软给9x打布丁支持unicode不算。

API有两个版本: A(ASNI)版本和W(Unicode)版本. A版本调用时候会用ANSI来封送字符串,一般是win95/98上。W版本用Unicode来封送,在NT,2K和XP上。

.Net和win32交互的时候,默认是使用CharSet.Ansi来传送。

在 DllImportAttribute.ExactSpelling 字段为 true 时(它是 Visual Basic .NET 中的默认值),平台调用将只搜索您指定的名称。例如,如果指定 MessageBox,则平台调用将搜索 MessageBox,如果它找不到完全相同的拼写则失败。

当 ExactSpelling 字段为 false(它是 C++ 托管扩展和 C# 中的默认值),平台调用将首先搜索未处理的别名 (MessageBox),如果没有找到未处理的别名,则将搜索已处理的名称 (MessageBoxA)。请注意,ANSI 名称匹配行为与 Unicode 名称匹配行为不同。

C#通过p/invoke调用C++ DLL (转)_.net //CharSet.Ansi will call MessageBoxA

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net //CharSet.Unicode will call MessageBoxW

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net [DllImport("user32.dll",EntryPoint="MessageBox",CharSet=CharSet.Ansi)]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static extern int MyMsg(int hWnd,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string msg,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string caption,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net int type );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net private void button1_Click(object sender, System.EventArgs e)

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 MyMsg( 0, "Msg:hello", "Caption:Hello",0 );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18 }

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

6,Dll里面的callback函数如何实现?看下面这个例子:

C#通过p/invoke调用C++ DLL (转)_.netdelegate bool CallBackDef( int hWnd, int lParm );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net [DllImport("user32.dll")]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static extern int GetWindowText( int hWnd,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net StringBuilder text,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net int count );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net [DllImport("user32.dll")]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static extern int EnumWindows(CallBackDef callback, int lParam );

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static bool PrintWindow(int hWnd, int lParm )

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 StringBuilder text = new StringBuilder(255);

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 GetWindowText( hWnd, text, 255 );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 Console.WriteLine( text.ToString() );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 return true;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18 }

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net private void button1_Click(object sender, System.EventArgs e)

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 CallBackDef callBack = new CallBackDef( PrintWindow );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 EnumWindows( callBack, 0 );

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18 }

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

7,MarshalAs如何用,什么时候用?

在MessageBox传递string去Dll的时,C#编译器知道Win32LPSTR等价与一个C#字符串。但是如果想覆盖默认.Net行为, 这时候就需要MarshallAs

C#通过p/invoke调用C++ DLL (转)_.net[DllImport("user32.dll", CharSet=CharSet.Unicode )]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net static extern int MessageBox( int hWnd,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net [MarshalAs(UnmanagedType.LPWStr)]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string msg,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net [MarshalAs(UnmanagedType.LPWStr)]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net string caption,

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net int type);

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net


8,我怎么知道要调用的函数在那个dll了?

这个问题我不会比你更清楚,特殊的函数应该在你特殊的dll中。Win32中常用的几个dll是user32.dll, kernel32.dll和GDI32.dll.用dumpbin -exports kernel32.dll可以看到这个dll所有的API函数。


9,相互之间传递struct怎么办?我是说传递很复杂的struct?

传递一个结构,这个要用到StructLayoutAttribute属性。比如:

PtInRect 具有以下非托管签名:

BOOL PtInRect(const RECT *lprc, POINT pt);

请注意,由于函数需要指向 RECT 类型的指针,必须通过引用来传递 Rect 结构。

C#通过p/invoke调用C++ DLL (转)_.netusing System.Runtime.InteropServices;

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net[StructLayout(LayoutKind.Sequential)]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.netpublic struct Point

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 public int x;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 public int y;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18}

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net[StructLayout(LayoutKind.Explicit)]

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.netpublic struct Rect

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 [FieldOffset(0)] public int left;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 [FieldOffset(4)] public int top;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 [FieldOffset(8)] public int right;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 [FieldOffset(12)] public int bottom;

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18}

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.netclass Win32API

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_平台调用_12C#通过p/invoke调用C++ DLL (转)_.net_13C#通过p/invoke调用C++ DLL (转)_平台调用_14{

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 [DllImport("User32.dll")]

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_搜索_15 public static extern bool PtInRect(ref Rect r, Point p);

C#通过p/invoke调用C++ DLL (转)_搜索_15

C#通过p/invoke调用C++ DLL (转)_ico_18}

C#通过p/invoke调用C++ DLL (转)_.net

C#通过p/invoke调用C++ DLL (转)_.net

10,哪里有不错的教程,我可以学到更详细的东西?

google一下多的是。MSDN里面也有一些不错的教程:(vs.net 2003)




11,最后,这位大哥,你说了很多,我想问一个对我来说最关键的问题,我看了你的东西,似是而非,不会用怎么办?