Допустим, у меня есть внешний метод, который используется для вычисления квадратного корня из числа. Нравиться:
using System;
public static class Program
{
Public static extern double Sqrt(double x);
public static void Main(string[] args)
{
Console.WriteLine(Sqrt(64));
}
}
Чтобы внешний метод работал, мне нужно загрузить DLL, что обычно делается с помощью DllImport
.
Но допустим, я хочу загрузить DLL во время выполнения, вызвав метод, как в Java:
System.load(“Path to DLL”);
Можно ли это сделать на С#?
Вы можете импортировать тот же LoadLibrary
, к которому вы привыкли.
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string lib);
[DllImport("kernel32.dll")]
public static extern void FreeLibrary(IntPtr module);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr module, string proc);
Пример использования (вы должны добавить обработку ошибок):
delegate int MyDelegate(int n, [MarshalAs(UnmanagedType.LPStr)] string s);
var module = LoadLibrary("Foo.dll");
var method = GetProcAddress(module, "doSomething");
var doSomething = (MyDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(MyDelegate));
var result = doSomething(2, "Hello world!");
FreeLibrary(module);
См. Эта статья
Почти уверен, что это то же самое, вы просто установите атрибут MarshalAs
для параметров в объявлении MyDelegate
.
Если у
doSomething
есть аргументы строкового типа или других непримитивных типов, мне нужно будет маршалировать такие аргументы вручную, я прав? И нет никакого способа добиться автоматического маршалинга с помощью атрибутов или чего-то подобного, как мы можем сделать дляDllImport
.