DllImport or LoadLibrary for best performance

后端 未结 4 1576
温柔的废话
温柔的废话 2020-12-30 12:09

I have external .DLL file with fast assembler code inside. What is the best way to call functions in this .DLL file to get best performance?

相关标签:
4条回答
  • 2020-12-30 12:40

    Your DLL might be in python or c++, whatever , do the same as follow.

    This is your DLL file in C++.

    header:

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

    Source code file

    #include "DynamicDLLToCall.h"
    
    int MultiplyByTen(int numberToMultiply)
    {
        int returnValue = numberToMultiply * 10;
        return returnValue;
    } 
    

    Take a look at the following C# code:

    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);
        }
    } 
    
    0 讨论(0)
  • 2020-12-30 12:41

    Assuming your target platform is the same as said native dll. You can use DLLImport to pinvoke LoadLibrary and use LoadLibrary to load the native dll into your process. Then use DllImport to pinvoke GetProcAddress.

    Then you can define delegates for all the methods exported in said dll that you want to call.

    Next you use the Marshal.GetDelegateForFunctionPointer to set your delegate from GetProcAddress.

    You create a static class that does this stuff once in the constructor. Then you can call your delegates to invoke the native exported functions in the dll, without having DllImport on everything. Much cleaner, and I'm pretty sure it's a lot faster and will probably completely bypass before mentioned parameter checks.

    SO you would have a slow initialization, but once loaded, would run fast imo. Haven't tested this.

    Here's a blog on it from my source.

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

    0 讨论(0)
  • 2020-12-30 12:43

    I think DLLImport and LoadLibrary have different goals. If you use native .dll, you should use DllImport. If you use .NET assembly, you should use LoadAssembly.

    Actually, you can dynamically load native assembly too, see this example: dynamically-calling-an-unmanaged-dll-from-.net

    0 讨论(0)
  • 2020-12-30 12:53

    The only way to answer this question is to time both options, a task which is trivially easy. Making performance predictions without timing is pointless.

    Since we don't have your code, only you can answer your question.

    0 讨论(0)
提交回复
热议问题