【问题标题】:c# how to call functions from function table?c#如何从函数表中调用函数?
【发布时间】:2016-03-26 01:47:19
【问题描述】:

我的项目中有 .NET DLL 导入库,我想调用的函数取自函数 table (List<string>) 的名称。

假设它们都具有相同的返回类型和参数。

我有 functions_table[] 类似“Func1”、“Func2”......

我从那个表中随机选择(真的很像 List)并在我的程序中调用它。

据我所知,C# delegate 不适用于此解决方案。

我想随机选择名称为 Func1() 的函数(例如)从托管 C# 代码及其参数中调用。

如何实现?

【问题讨论】:

    标签: c# function dynamic dll delegates


    【解决方案1】:

    因为你说这个函数必须从托管代码中调用,我相信函数 DLL 是原生的。所以首先,你需要一些本地方法来加载\释放这个库并调用函数:

    public static class NativeMethods
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr LoadLibrary(string filename);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool FreeLibrary(IntPtr hModule);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    }
    

    然后用这段代码加载DLL:

    var libHandle = NativeMethods.LoadLibrary(fileName);
    if (libHandle == IntPtr.Zero)
    {
        var errorCode = Marshal.GetLastWin32Error();
        // put error handling here if you need
    }
    

    然后释放:

    if (libHandle != IntPtr.Zero)
        NativeMethods.FreeLibrary(libHandle);
    

    您还需要委托人来拨打电话。例如,

    delegate int FuncDelegate(int arg1, bool arg2);
    

    然后从DLL中调用函数:

    var func1Address = NativeMethods.GetProcAddress(libHandle, "Func1");
    var func1 = (FuncDelegate)Marshal.GetDelegateForFunctionPointer(func1Address, typeof(FuncDelegate));
    var result = func1(42, true);
    

    当然,您可以(并且可能应该)缓存这些函数:

    private Dictionary<string, FuncDelegate> _functionsCache = new Dictionary<string,FuncDelegate>();
    private int CallFunc(string funcName, int arg1, bool arg2)
    {
        if (!_functionsCache.ContainsKey(funcName))
        {
            var funcAddress = NativeMethods.GetProcAddress(libHandle, funcName);
            var func = (FuncDelegate)Marshal.GetDelegateForFunctionPointer(funcAddress, typeof(FuncDelegate));
            _functionsCache.Add(funcName, func);
        }
    
        return _functionsCache[funcName](arg1, arg2);
    }
    

    【讨论】:

    • thx v1rusw0rm,但我的函数不是来自 C/C++ DLL,它也是托管代码,只是来自另一个 dll。
    【解决方案2】:
    MethodInfo handler = GetType.GetMethod("NameMethod");
    handler.Invoke(context, new object[] {parameters}
    

    成功了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多