带有泛型委托的 C# GetDelegateForFunctionPointer

Job*_*ick 6 c#

我需要动态调用dll函数。

我正在使用标准 Windows API 来加载 dll 并获取 proc 地址。

在检索 proc 的 IntPtr 后,我尝试将其转换为委托:

Func<int> inv = (Func<int>)Marshal.GetDelegateForFunctionPointer(proc, typeof(Func<int>));
Run Code Online (Sandbox Code Playgroud)

但它失败了,因为 typeof(Func) 返回泛型类型。

有没有什么干净的方法来完成我想要做的事情,而无需声明成员委托并将其用作类型?

我的意思是我正在努力避免以下冗余:

//I need this member only for typeof operator
private delegate int RunDll();
RunDll inv = (RunDll)Marshal.GetDelegateForFunctionPointer(proc, typeof(RunDll));
Run Code Online (Sandbox Code Playgroud)

Ill*_*ack 8

如果委托类型是动态的并且您不知道参数,情况会更糟。然后您可以使用.NET 方法来生成它。

\n\n
public static class DelegateCreator\n{\n    private static readonly Func<Type[],Type> MakeNewCustomDelegate = (Func<Type[],Type>)Delegate.CreateDelegate(typeof(Func<Type[],Type>), typeof(Expression).Assembly.GetType("System.Linq.Expressions.Compiler.DelegateHelpers").GetMethod("MakeNewCustomDelegate", BindingFlags.NonPublic | BindingFlags.Static));\n\n    public static Type NewDelegateType(Type ret, params Type[] parameters)\n    {\n        Type[] args = new Type[parameters.Length];\n        parameters.CopyTo(args, 0);\n        args[args.Length-1] = ret;\n        return MakeNewCustomDelegate(args);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xc2\xa0

\n\n
DelegateCreator.NewDelegateType(typeof(int)) //returns non-generic variant of Func<int>\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这正是我所需要的,一个非泛型委托类型创建者,这样我就可以在其上调用 Marshal.GetFunctionPointerForDelegate 。:) (3认同)

Eam*_*nne 2

根据文档,该 API 根本不支持泛型。请注意,这并不是一个很大的损失 - 毕竟,您只需要指定一次签名即可;唯一的缺点是你不能内联指定它 - usingFunc<int>不需要这种间接,但是(由于强制转换)它在某种意义上实际上更加多余。

顺便说一句,您可能想查看普通的旧版本DllImport- 如果提前知道 DLL 和函数,则不需要执行此手动委托包装。