Установить атрибут DllImport динамически - PullRequest
6 голосов
/ 12 мая 2010

Я использую внешнюю неуправляемую dll, используя PInvoke и атрибут DllImport. например.

[DllImport("mcs_apiD.dll", CharSet = CharSet.Auto)]
private static extern byte start_api(byte pid, byte stat, byte dbg, byte ka);

Мне интересно, возможно ли каким-то образом изменить детали файла dll (в данном примере mcs_apiD.dll), если, например, я хотел собрать другую версию dll

Ответы [ 2 ]

7 голосов
/ 12 мая 2010

Да, это возможно, вам придется выполнять часть работы, которую выполняет маршаллер P / Invoke. Загрузка DLL и поиск точки входа экспортируемой функции. Начните с объявления делегата, чья подпись соответствует экспортируемой функции:

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

Затем используйте такой код:

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

Конечно, есть много способов ошибиться. Обратите внимание, что вы должны использовать фактическое экспортированное имя из DLL, вы больше не получаете помощь от маршаллера P / Invoke, чтобы помочь с оформлением имени. Используйте dumpbin.exe / exports в DLL, если вы не уверены, как выглядит имя экспорта.

2 голосов
/ 12 мая 2010

вы не можете изменить имя dll, но вы можете изменить путь к загружаемой библиотеке (например, читая ее из реестра или файла конфигурации) и загрузить ее вручную с помощью функции LoadLibrary kernel32: см. мой ответ там .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...