C# 如何通过“获取.net托管方法指针”;方法名称“;可以在本机代码上调用的 前提条件

C# 如何通过“获取.net托管方法指针”;方法名称“;可以在本机代码上调用的 前提条件,c#,reflection,interop,clr,cil,C#,Reflection,Interop,Clr,Cil,我将获取其指针的.net方法是: 公共静态法 没有过载 参数和返回值仅为ValueType(不安全指针、基元类型、非托管结构) 理由 获取方法指针,以便在C++程序中调用.< /P> 这对我有效,但我需要为每个方法声明委托 我想摆脱一遍又一遍地做事情 在.net端: [UnmanagedFunctionPointer(CallingConvention.StdCall)] 公共委派无效更新委派(浮动增量); 公共静态void*getUpdateInter() { var delegateIn

我将获取其指针的.net方法是:

  • 公共静态法
  • 没有过载
  • 参数和返回值仅为ValueType(不安全指针、基元类型、非托管结构)
理由

获取方法指针,以便在C++程序中调用.< /P> 这对我有效,但我需要为每个方法声明委托

我想摆脱一遍又一遍地做事情

在.net端:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
公共委派无效更新委派(浮动增量);
公共静态void*getUpdateInter()
{
var delegateInstance==新的updateLegate(更新);
var pfnUpdate=Marshal.GetFunctionPointerForDelegate(delegateInstance);
返回(无效*)pfnUpdate;
}
公共静态更新(浮点增量)=>{…}
在C++方面:

typedef void(_stdcall*FuncPtr)(浮动);
void foo()
{
//只是显示pfnUpdate来自何处的伪代码。
FuncPtr pfnUpdate=(FuncPtr)GetUpdatePointer();
pfnUpdate(0.01f);
}
我想要什么 在c#中,我导出本机代码的GetMethodPointer。它将返回一个指向指定方法的函数指针,本机程序可以通过stdcall调用约定调用该指针

//避免gc收集此对象
静态列表首选项=新列表();
公共不安全静态void*GetMethodPointer(字符串名称)
{
System.Reflection.MethodInfo MethodInfo=typeof(PhysicsMain).GetMethod(name);
//还使用[UnmanagedFunctionPointer(CallingConvention.StdCall)]属性标记此委托
类型delegateType=ConstructDelegateTypeWithMethodInfo(methodInfo);
var delegateInstance=Delegate.CreateDelegate(delegateType,methodInfo);
KeepReference.Add(delegateInstance);
return(void*)Marshal.GetFunctionPointerForDelegate(delegateInstance);
}
我需要ConstructDelegateTypeWithMethodInfo来创建与指定方法具有相同签名的委托。并为其标记[UnmanagedFunctionPointer(CallingConvention.StdCall)]属性,以便将其封送为函数指针


我认为它可能使用IL、反射,甚至Asm来实现这一点。或者使用IL编写整个GetMethodPointer方法。

在您的示例中,假设该方法的类是know function(
PhysicsMain

如果还知道
updateLegate
,您可以轻松使用它:

Type delegateType = typeof(UpdateDelegate);
var delegateInstance = Delegate.CreateDelegate(delegateType, methodInfo);
但您也可以仅按名称获取此类型:

Type delegateType = Type.GetType("Namespace.ClassName+UpdateDelegate");
var delegateInstance = Delegate.CreateDelegate(delegateType, methodInfo);

您可以查看
delegateType.CustomAttributes
并验证该类型是否具有
UnmanagedFunctionPointer
属性。

在您的示例中,您假设该方法的类是know function(
PhysicsMain

如果还知道
updateLegate
,您可以轻松使用它:

Type delegateType = typeof(UpdateDelegate);
var delegateInstance = Delegate.CreateDelegate(delegateType, methodInfo);
但您也可以仅按名称获取此类型:

Type delegateType = Type.GetType("Namespace.ClassName+UpdateDelegate");
var delegateInstance = Delegate.CreateDelegate(delegateType, methodInfo);

您可以查看
delegateType.CustomAttributes
并验证该类型是否具有
UnmanagedFunctionPointer
属性。

最近,我终于找到了一个解决方案。首先,我遇到了Expression.GetDelegateType所给出的
Expression.GetDelegateType
。但它对我不起作用,因为
Marshal.GetFunctionPointerForDelegate
不支持通过
Expression.GetDelegateType
生成的泛型委托类型。我想在
Expression.GetDelegateType
的实现中可能有线索。因此,我浏览了一下,得到了一个名为
MakeNewCustomDelegate
的内部方法。这给出了有关如何调用内部方法的代码。事情很容易解决


编辑:我忘了说,委托的默认非托管调用约定是stdcall,因此我们不需要显式地用[UnmanagedFunctionPointer(CallingConvention.stdcall)]标记委托。

最近,我终于找到了一个解决方案。首先,我遇到了Expression.GetDelegateType所给出的
Expression.GetDelegateType
。但它对我不起作用,因为
Marshal.GetFunctionPointerForDelegate
不支持通过
Expression.GetDelegateType
生成的泛型委托类型。我想在
Expression.GetDelegateType
的实现中可能有线索。因此,我浏览了一下,得到了一个名为
MakeNewCustomDelegate
的内部方法。这给出了有关如何调用内部方法的代码。事情很容易解决


编辑:我忘了说,委托的默认非托管调用约定是stdcall,因此我们不需要显式地用[UnmanagedFunctionPointer(CallingConvention.stdcall)]标记委托。

对不起,可能我没有清楚地表达出来。没有名为“UpdateDelegate”的委托类型。没有预定义的代理。因为有许多方法具有不同的签名,所以我不想为每个方法预定义委托。我只想在运行时使用MethodInfo生成委托类型。实际上,MethodInfo包含关于为此方法构造委托类型的所有信息。但是谢谢你的帮助。对不起,也许我没有说清楚。没有名为“UpdateDelegate”的委托类型。没有预定义的代理。因为有许多方法具有不同的签名,所以我不想为每个方法预定义委托。我只想在运行时使用MethodInfo生成委托类型。实际上,MethodInfo包含关于为此方法构造委托类型的所有信息。但是谢谢你的帮助。