Search code examples
c#dlldllimportloadlibrarygetprocaddress

How to load dll dynamically and pass/get value to it?


In DllImport I can do this:

[DllImport(".../Desktop/Calculate.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int Sub(int a, int b);

But I want to decide which dll to load at run time. So I'm not using DllImport but try this:

using System;
using System.Runtime.InteropServices;

namespace TestCall   
{
    class Program
    {
        [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
        static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
        [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
        static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
        static extern bool FreeLibrary(int hModule);
        delegate void CallMethod();
        static void Main(string[] arg)  //pass in string array
        {
            string DllName = ".../Desktop/Calculate.dll";  //would be like: string  DllName = ChooseWhatDllToCall();
            string FuncName = "Sub";                       //would be like: string FuncName = ChooseWhatFuncToUse();
            int hModule = LoadLibrary(DllName); // you can build it dynamically 
            if (hModule == 0) return;
            IntPtr intPtr;
            CallMethod action;

            intPtr = GetProcAddress(hModule, FuncName);
            action = (CallMethod)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(CallMethod));
            action.Invoke();
        }
    }
}

But how can I define Sub as int Sub(int a, int b); like I'm using DllImport?


Solution

  • You can define a delegate as follows:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate Int32 Sub(Int32 a, Int32 b);
    

    and then, in your code:

    Sub sub = (Sub)Marshal.GetDelegateForFunctionPointer(intPtr,typeof(Sub));
    
    Int32 a = 5;
    Int32 b = 8;
    Int32 result = sub(a, b);