Set DllImport attribute dynamically

后端 未结 2 768
死守一世寂寞
死守一世寂寞 2020-11-29 09:46

I am making use of an external unmanaged dll using PInvoke and the DllImport attribute. eg.

[DllImport(\"mcs_apiD.dll\", CharSet = CharSet.Auto)]
private s         


        
2条回答
  •  Happy的楠姐
    2020-11-29 10:23

    Yes this is possible, you'll have to do part of the job that the P/Invoke marshaller does. Loading the DLL and finding the entry point of the exported function. Start by declaring a delegate whose signature matches the exported function:

     private delegate byte start_api(byte pid, byte stat, byte dbg, byte ka);
    

    Then use code like this:

     using System.ComponentModel;
     using System.Runtime.InteropServices;
      ...
    
        static IntPtr dllHandle;
      ...
            if (dllHandle == IntPtr.Zero) {
                dllHandle = LoadLibrary("mcs_apiD.dll");
                if (dllHandle == IntPtr.Zero) throw new Win32Exception();
            }
            IntPtr addr = GetProcAddress(dllHandle, "_start_api@16");
            if (addr == IntPtr.Zero) throw new Win32Exception();
            var func = (start_api)Marshal.GetDelegateForFunctionPointer(addr, typeof(start_api));
            var retval = func(1, 2, 3, 4);
      ...
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr LoadLibrary(string name);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string name);
    

    Lots of ways to get this wrong of course. Do note that you have to use the actual exported name from the DLL, you no longer get the help from the P/Invoke marshaller to help with name decoration. Use dumpbin.exe /exports on the DLL if you are not sure what the export name looks like.

提交回复
热议问题