Когда в C# вызываем функцию из DLL, то выглядит это, например, так:
[DllImport("NameDLL.dll")]
public static extern bool Func (string str, int param);
Всё работает без проблем, но непонятно, как вызывать функцию, если вместо конкретной "NameDLL.dll" из каталога программы нужно будет передать полный путь к библиотеке (например,если библиотека находится в подкаталоге программы), но не заранее заданнный, а тот, который определится в момент вызова (путь к приложению + подкаталог с заданным именем + имя библиотеки). В C# можно получить путь к приложению, однако это будет string, а не const string, который и нужно передать внутрь DllImport. Преобразовать string в const string средствами C# вроде возможным не представляется (да и это, наверное, не совсем правильный путь).
Так каким образом можно динамически получить и передать полный путь к библиотеке в виде const string?
Здравствуйте, Garris, Вы писали:
G>Когда в C# вызываем функцию из DLL, то выглядит это, например, так: G>[DllImport("NameDLL.dll")] G>public static extern bool Func (string str, int param); G>Всё работает без проблем, но непонятно, как вызывать функцию, если вместо конкретной "NameDLL.dll" из каталога программы нужно будет передать полный путь к библиотеке (например,если библиотека находится в подкаталоге программы), но не заранее заданнный, а тот, который определится в момент вызова (путь к приложению + подкаталог с заданным именем + имя библиотеки). В C# можно получить путь к приложению, однако это будет string, а не const string, который и нужно передать внутрь DllImport. Преобразовать string в const string средствами C# вроде возможным не представляется (да и это, наверное, не совсем правильный путь). G>Так каким образом можно динамически получить и передать полный путь к библиотеке в виде const string?
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace LibraryClient
{
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int DoubleIt(int value);
static void Main(string[] args)
{
IntPtr pDll = NativeMethods.LoadLibrary("LibraryC.dll");
if(pDll == IntPtr.Zero)
throw new Win32Exception();
IntPtr pProc = NativeMethods.GetProcAddress(pDll, "DoubleIt");
if(pProc == IntPtr.Zero)
throw new Win32Exception();
var doubleDelegate = (DoubleIt)Marshal.GetDelegateForFunctionPointer(pProc, typeof(DoubleIt));
int arg = 2;
int result = doubleDelegate(arg);
bool isFreed = NativeMethods.FreeLibrary(pDll);
Console.WriteLine("If we double {0} we get {1}", arg, result);
if(!isFreed)
Console.WriteLine("Library could not be freed.");
Console.ReadLine();
}
}
static class NativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[ResourceExposure(ResourceScope.Process)]
public static extern IntPtr LoadLibrary(string libFilename);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
static internal extern IntPtr GetProcAddress(IntPtr HModule, [MarshalAs(UnmanagedType.LPStr), In] string funcName/*lpcstr*/);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[ResourceExposure(ResourceScope.Process)]
public static extern bool FreeLibrary(IntPtr hModule);
}
}
Компилировать клиента на C# пришлось под Win32, если компилировалось под AnyCPU/x64, то получалась мало понятная ошибка "%1 is not a valid Win32 application".
Уточню на всякий случай, что в LoadLibrary() можно теперь любой путь к dll указать динамически, а то вдруг не понятно Просто в моем примере библиотека находилась в той же директории, что и клиент.
Re[3]: C# - вызов из библиотеки по полному пути
От:
Аноним
Дата:
20.02.11 16:33
Оценка:
Здравствуйте, MozgC, Вы писали:
MC>Уточню на всякий случай, что в LoadLibrary() можно теперь любой путь к dll указать динамически, а то вдруг не понятно Просто в моем примере библиотека находилась в той же директории, что и клиент.
Здравствуйте, MozgC, Вы писали:
MC>Компилировать клиента на C# пришлось под Win32, если компилировалось под AnyCPU/x64, то получалась мало понятная ошибка "%1 is not a valid Win32 application".