Установить атрибут DllImport динамически
7146 просмотра
2 ответа
Я использую внешнюю неуправляемую 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 Источник Размещён: 13.11.2019 11:36Ответы (2)
8 плюса
Да, это возможно, вам придется выполнять часть работы, которую выполняет маршаллер 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:582 плюса
Вы не можете изменить имя dll, но вы можете изменить путь к загружаемой библиотеке (например, читая ее из реестра или файла конфигурации) и загрузить ее вручную с LoadLibrary
помощью функции kernel32: см. мой ответ там .
Вопросы из категории :
- c# Преобразовать десятичную в двойную?
- c# Как рассчитать чей-то возраст в C #?
- c# Как вы сортируете словарь по значению?
- c# В чем разница между int и Integer в Java и C #?
- c# Как создать новый экземпляр объекта из Типа
- c# Datatable против Dataset
- c# Setting Objects to Null/Nothing after use in .NET
- c# Конвертировать целые числа в записанные числа
- c# Почему я не могу иметь абстрактные статические методы в C #?
- c# Как я могу оценить код C # динамически?
- pinvoke Маршал "char *" в C #
- pinvoke Как получить родительский процесс в .NET управляемым способом
- pinvoke Доступ к файлам за пределами MAX_PATH в C # /. NET
- pinvoke «Была сделана попытка загрузить программу с неверным форматом», даже если платформы одинаковы
- pinvoke Проверьте, присутствует ли DLL в системе
- pinvoke Установить атрибут DllImport динамически
- pinvoke Удаление строки заголовка внешнего приложения с помощью c #
- pinvoke Определить закрытие и открытие крышки ноутбука
- pinvoke pinvokestackimbalance - как это исправить или отключить?
- pinvoke Возвращение Struct из VC ++ в C #