DllImport或LoadLibrary以获得最佳性能

问题描述 投票:6回答:4

我有外部.DLL文件,里面有快速汇编程序代码。调用此.DLL文件中的函数以获得最佳性能的最佳方法是什么?

c# dllimport loadlibrary
4个回答
10
投票

您的DLL可能是python或c ++,无论如何,请执行相同的操作。

这是您在C ++中的DLL文件。

标题:

extern "C" __declspec(dllexport) int MultiplyByTen(int numberToMultiply);

源代码文件

#include "DynamicDLLToCall.h"

int MultiplyByTen(int numberToMultiply)
{
    int returnValue = numberToMultiply * 10;
    return returnValue;
} 

看看下面的C#代码:

static class NativeMethods
{
    [DllImport("kernel32.dll")]
    public static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    [DllImport("kernel32.dll")]
    public static extern bool FreeLibrary(IntPtr hModule);
}

class Program
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate int MultiplyByTen(int numberToMultiply);

    static void Main(string[] args)
    {
            IntPtr pDll = NativeMethods.LoadLibrary(@"PathToYourDll.DLL");
            //oh dear, error handling here
            //if (pDll == IntPtr.Zero)

            IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "MultiplyByTen");
            //oh dear, error handling here
            //if(pAddressOfFunctionToCall == IntPtr.Zero)

            MultiplyByTen multiplyByTen = (MultiplyByTen)Marshal.GetDelegateForFunctionPointer(
                                                                                    pAddressOfFunctionToCall,
                                                                                    typeof(MultiplyByTen));

            int theResult = multiplyByTen(10);

            bool result = NativeMethods.FreeLibrary(pDll);
            //remaining code here

            Console.WriteLine(theResult);
    }
} 

2
投票

假设您的目标平台与所述本机dll相同。您可以使用DLLImport对LoadLibrary进行pinvoke,并使用LoadLibrary将本机dll加载到您的进程中。然后使用DllImport对GetProcAddress进行pinvoke。

然后,您可以为要调用的所有dll中导出的所有方法定义委托。

接下来,使用Marshal.GetDelegateForFunctionPointer从GetProcAddress设置委托。

您创建一个静态类,在构造函数中执行此操作一次。然后,您可以调用您的委托调用dll中的本机导出函数,而不必在所有内容上使用DllImport。更清洁,我很确定它更快,并且可能在提到的参数检查之前完全绕过。

所以你会有一个缓慢的初始化,但一旦加载,将快速运行imo。没试过这个。

这是我的消息来源的博客。

http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_.aspx


1
投票

回答这个问题的唯一方法是计算两个选项,这个任务非常容易。在没有时间的情况下进行性能预测毫无意义。

由于我们没有您的代码,只有您可以回答您的问题。


0
投票

我认为DLLImport和LoadLibrary有不同的目标。如果使用本机.dll,则应使用DllImport。如果使用.NET程序集,则应使用LoadAssembly。

实际上,您也可以动态加载本机程序集,请参阅此示例:dynamically-calling-an-unmanaged-dll-from-.net

© www.soinside.com 2019 - 2024. All rights reserved.