`
blogfeifei
  • 浏览: 1198404 次
文章分类
社区版块
存档分类
最新评论

P/Invoke和Reverse P/Invoke

 
阅读更多

.Net与动态链接库、COM组件的关系大致如下:

interop

1. P/Invoke

P/Invoke(platform invoke)是.NET调用本地代码(native code)的一种比较轻便的方式。只需要将本地代码编写成动态链接库,然后在c#代码中,声明一个外部静态函数,并且用DllImport属性指明动态连接库的入口。举例如下:

using
 System;
using System.Runtime.InteropServices;

class PInvoke
{
[DllImportAttribute("user32.dll" , EntryPoint = "MessageBoxW" )]
public static extern int MessageBoxW(
[In]System.IntPtr hWnd,
[In][MarshalAs(UnmanagedType.LPWStr)] string lpText,
[In][MarshalAs(UnmanagedType.LPWStr)] string lpCaption,
uint uType);

public static void Main()
{
MessageBoxW(IntPtr.Zero, "Hello" , "Interop" , 0);
}
}
MessageBoxW是一个在user32.dll中已经实现了的函数,这里只需要声明一下它,然后就可以调用了

2. Reverse P/Invoke

接着,我们来看看在本地代码中调用.NET方法。本地代码需要拿到一个.NET委托(delegate),然后把这个delegate当作一个函数指针使用,示例如下:

using
 System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class Program
{
internal delegate void DelegateMessageBox([MarshalAs(UnmanagedType.LPWStr)]string msg);

[DllImport("Native.dll" , CallingConvention = CallingConvention.Cdecl)]
static extern void NativeMethod(DelegateMessageBox d);

public static void ShowMessageBox(string msg)
{
MessageBox.Show(msg);
}

public static void Main()
{
NativeMethod(new DelegateMessageBox(ShowMessageBox));
}
}

这个例子中,我们希望本地代码能够调用托管函数ShowMessageBox来显示一个对话框。为了让本地代码可以调用这个函数,我们根据它的声明,定了了一个delegate,并且通过P/Invoke把这个委托传给了本地代码。本地代码可以如下调用托管代码:

#include
 <stdio.h>
#include <wtypes.h>

extern "C" {
__declspec (dllexport ) void NativeMethod(void (__stdcall *pShowMsgBox)(WCHAR *wChar))
{
(*pShowMsgBox)(L"hello reverse interop" );
}
}

注意到托管代码中的委托到了本地代码中,就是一个函数指针,本地代码可以像一个普通的函数指针一般调用托管代码。

——源文引自http://blogs.msdn.com/silverlightshanghai/archive/2009/03/29/net-interop-p-invoke-reverse-p-invoke.aspx

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics