函数介绍
摘自MSDN
命名空间: System.Runtime.InteropServices
函数:Marshal.GetDelegateForFunctionPointer
(将非托管函数指针转换为委托)
publicstatic Delegate GetDelegateForFunctionPointer( IntPtr ptr, Type t )
参数
-
ptr
-
类型:System.IntPtr
要转换的非托管函数指针。
-
t
-
类型:
System.Type
要返回的委托的类型。
返回值
类型: System.Delegate委托实例,可强制转换为适当的委托类型。
异常 | 条件 |
---|---|
ArgumentException | t 参数不是委托或泛型。 |
ArgumentNullException | ptr 参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。 - 或 - t 参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。 |
在 .NET Framework 1.0 或 1.1 版中,可以将表示托管方法的委托作为函数指针传递给非托管代码,因此,非托管代码可以通过函数指针调用托管方法。非托管代码也可以将该函数指针传递回托管代码,指针可以正确解析为基础托管方法。
在 .NET Framework 2.0 及更高版本中,可以使用 GetDelegateForFunctionPointer 方法和GetFunctionPointerForDelegate 方法双向封送委托。 用 GetDelegateForFunctionPointer,ptr 将导入为System.IntPtr。 通过调用 GetFunctionPointerForDelegate 可以为托管委托获得 System.IntPtr,然后作为参数传递;此后可以从非托管方法中调用。 注意,在 .NET Framework 2.0 及更高版本中,参数封送拆收器还可将函数指针封送到委托。
GetDelegateForFunctionPointer 方法具有下列限制:
-
在互操作方案中不支持泛型。
-
不能将无效的函数指针传递给此方法。
-
此方法只能用于纯非托管函数指针。
-
不能将此方法用于通过 C++ 或从 GetFunctionPointer 方法获取的函数指针。
-
此方法不能用于由指向另一托管委托的函数指针创建委托。
- SecurityCriticalAttribute
需要完全信任直接调用方。此成员不能由部分受信任或透明的代码使用。
函数:Marshal.GetFunctionPointerForDelegate
(将委托转换为可从非托管代码调用的函数指针)
publicstatic IntPtr GetFunctionPointerForDelegate( Delegate d )
参数
-
d
-
类型:
System.Delegate
要传递给非托管代码的委托。
返回值
类型: System.IntPtr一个可传递给非托管代码的值,非托管代码使用该值来调用基础托管委托。
异常 | 条件 |
---|---|
ArgumentException | d 参数是泛型类型。 |
ArgumentNullException | d 参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。 |
委托 d 转换为可使用 __stdcall 调用约定传递给非托管代码的函数指针。
必须以手动方式阻止垃圾回收器从托管代码中回收该委托。垃圾回收器不跟踪对非托管代码的引用。
例
例如一个函数指针定义为:
typedef int (*FUN)(int iType,void *pvArgs);
而一个委托定义为:
public delegate int TEST_DLGT(int iType, IntPtr pvArgs);
则可以通过如下方法完成他们之间的互相转换
public delegate int TEST_DLGT(int iType, IntPtr pvArgs);
public Form1()
{
TEST_DLGT funCallBack1 = new TEST_DLGT(this.testfun);
IntPtr pvFun = Marshal.GetFunctionPointerForDelegate(funCallBack1);//可将pvFun强制转化为void*,再强制转化为FUN类型
TEST_DLGT funCallBack12 = (TEST_DLGT)Marshal.GetDelegateForFunctionPointer(pvFun, typeof(TEST_DLGT));
}
在托管C++中,则应写为:
int ClassName::Start(TEST_DLGT ^funCallBack1)//委托通常在托管代码(C#)中创建,传入由托管C++封装的类库。这里假设ClassName是一个CLR类库的接口类。
{
FUN pfun1=(FUN)(void*)Marshal::GetFunctionPointerForDelegate(funCallBack1);
TEST_DLGT ^funCallBack2=(TEST_DLGT^)Marshal::GetDelegateForFunctionPointer((IntPtr)(void*)pfun1, TEST_DLGT::typeid);
return 0;
}
----------------------------EOB--------------------------------