Всем добрый день.
Есть ли в .NET возможность вызвать ф-цию из unmanaged DLL по известному только в рантайме имени DLL и имени функции? Сигнатура ф-ции известна заранее.
т. е. что-то типа
CallNativeFunc("Some.DLL", "func", par1, par2, par3);
или
object libr = LoadLibrary("Some.DLL"); // это, вроде, понятно как сделать
CallFunc(libr, "func", par1, par2, par3); // а вот это не знаю как сделать.
Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
AB>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...
Вот только не вижу смысла так извращаться, тк не могу придумать сценарий когда надо неизвестно заранее имя функции и параметров из dll, да и вызывать придётся функции через Invoke, что тебе скорее всего тоже не по душе
В конце концов можешь заимпортить в дизайнтайме LoadLibrary и GetProcAddress, а дальше мучатся с ними из рантайма
Здравствуйте, bosco, Вы писали:
AB>>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
B>По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...
Верно, после тестирования мпроизводительность меня удовлетворила.
B>Вот только не вижу смысла так извращаться,
Иногда приходиться
Здравствуйте, Anton Burtsev, Вы писали:
AB>Здравствуйте, bosco, Вы писали:
AB>>>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
B>>По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...
AB>Верно, после тестирования мпроизводительность меня удовлетворила.
B>>Вот только не вижу смысла так извращаться,
AB>Иногда приходиться
Еще более глючный способ — основан на использовании Reflection.Emit
Я некорое время назад постил на сайте gotdotnet.ru пример, в котором
запускался метод по адресу (GetProcAddress) и по имени процедуры.
Сейчас наш сайт временно упал, ссылку пока дать не могу,
если не найдете — пишите — поищем вместе...
PS. Пример называется примерно как Ваш пост
Здравствуйте, Anton Burtsev, Вы писали:
AB>Всем добрый день.
AB>т. е. что-то типа
AB>CallNativeFunc("Some.DLL", "func", par1, par2, par3);
AB>
AB>или
AB>object libr = LoadLibrary("Some.DLL"); // это, вроде, понятно как сделать
AB>CallFunc(libr, "func", par1, par2, par3); // а вот это не знаю как сделать.
AB>
Можно, только придеться написать нэйтив ДЛЛ в которой будет всего одна функция — занимающаяся тем, что будет перенаправлять параметры вызова по переданной ей адресу.
что то типа такого:
extern "C"
{
__declspec(dllexport) DWORD __stdcall InvokeNative(DWORD funcptr);
__declspec(naked) DWORD __stdcall InvokeNative(DWORD funcptr)
{
__asm pop ecx // save return address
__asm pop edx // Get function pointer
__asm push ecx // Restore return address
__asm jmp edx // Transfer control to the function pointer
}
}
Это счастье используется примерно так:
[
DllImport("kernel32", CharSet=CharSet.Ansi)
]
private static extern int GetPrivateProfileSection(string lpAppName,
byte[] lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32")]
private extern static IntPtr LoadLibrary(string lpLibFileName);
[DllImport("kernel32")]
private extern static bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32", CharSet=CharSet.Ansi)]
private extern static int GetProcAddress(IntPtr hModule, string lpProcName);
// Обратить внимание: переходник объвляется параметрами целевой функции
[DllImport("NativeInvoke.dll", CharSet=CharSet.Ansi)]
private extern static int InvokeNative(int funcptr, string path);
protected void MyFunc(string path)
{
IntPtr hLib = LoadLibrary(path);
if (hLib == IntPtr.Zero)
throw new System.IO.
FileNotFoundException("No library", path);
int procAddr = GetProcAddress(hLib, s_MethodName);
int res = 0;
if (procAddr != 0)
res = InvokeNative(procAddr, path);
}
P.S C asm мог намудрить — вызывают сомнения возвращаемый результат

... << RSDN@Home 1.1.3 stable >>
Здравствуйте, Anton Burtsev, Вы писали:
AB>Всем добрый день.
AB>Есть ли в .NET возможность вызвать ф-цию из unmanaged DLL по известному только в рантайме имени DLL и имени функции? Сигнатура ф-ции известна заранее.
AB>т. е. что-то типа
AB>CallNativeFunc("Some.DLL", "func", par1, par2, par3);
AB>
AB>или
AB>object libr = LoadLibrary("Some.DLL"); // это, вроде, понятно как сделать
AB>CallFunc(libr, "func", par1, par2, par3); // а вот это не знаю как сделать.
AB>
AB>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
я думаю, что тут как раз к месту использовать MC++, и сделать все одной строчкой, а не городить огороды на ровном месте, не правда ли?