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
?
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);