Вопрос:

Установить атрибут DllImport динамически

c# pinvoke

7146 просмотра

2 ответа

34 Репутация автора

Я использую внешнюю неуправляемую 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

Автор: user226356 Источник Размещён: 12.05.2010 10:44

Ответы (2)


2 плюса

61064 Репутация автора

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

Автор: Gregory Pakosz Размещён: 12.05.2010 10:49

8 плюса

820289 Репутация автора

Да, это возможно, вам придется выполнять часть работы, которую выполняет маршаллер 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, если вы не уверены, как выглядит имя экспорта.

Автор: Hans Passant Размещён: 12.05.2010 12:58
Вопросы из категории :
32x32