P/Invoke без использования DllImport
От: Anton Burtsev Россия  
Дата: 22.04.04 07:09
Оценка:
Всем добрый день.

Есть ли в .NET возможность вызвать ф-цию из unmanaged DLL по известному только в рантайме имени DLL и имени функции? Сигнатура ф-ции известна заранее.

т. е. что-то типа
CallNativeFunc("Some.DLL", "func", par1, par2, par3);

или
object libr = LoadLibrary("Some.DLL"); // это, вроде, понятно как сделать
CallFunc(libr, "func", par1, par2, par3); // а вот это не знаю как сделать.


Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...
Re: P/Invoke без использования DllImport
От: bosco Россия  
Дата: 22.04.04 10:48
Оценка:
AB>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...

По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...

Вот только не вижу смысла так извращаться, тк не могу придумать сценарий когда надо неизвестно заранее имя функции и параметров из dll, да и вызывать придётся функции через Invoke, что тебе скорее всего тоже не по душе

В конце концов можешь заимпортить в дизайнтайме LoadLibrary и GetProcAddress, а дальше мучатся с ними из рантайма
Re[2]: P/Invoke без использования DllImport
От: Anton Burtsev Россия  
Дата: 22.04.04 12:12
Оценка:
Здравствуйте, bosco, Вы писали:

AB>>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...


B>По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...

Верно, после тестирования мпроизводительность меня удовлетворила.

B>Вот только не вижу смысла так извращаться,

Иногда приходиться
Re[3]: P/Invoke без использования DllImport
От: Аноним  
Дата: 22.04.04 14:01
Оценка:
Здравствуйте, Anton Burtsev, Вы писали:

AB>Здравствуйте, bosco, Вы писали:


AB>>>Есть вариант налету сгенерить класс с DllImport методом, скомпилить его и позвать. Но это будет тормозить...


B>>По-моему этот вариант — единственный. А тормозить будет во-первых 1 раз, а во вторых — не сильно...

AB>Верно, после тестирования мпроизводительность меня удовлетворила.

B>>Вот только не вижу смысла так извращаться,

AB>Иногда приходиться


Еще более глючный способ — основан на использовании Reflection.Emit
Я некорое время назад постил на сайте gotdotnet.ru пример, в котором
запускался метод по адресу (GetProcAddress) и по имени процедуры.
Сейчас наш сайт временно упал, ссылку пока дать не могу,
если не найдете — пишите — поищем вместе...

PS. Пример называется примерно как Ваш пост
Re: P/Invoke без использования DllImport
От: migel  
Дата: 23.04.04 06:26
Оценка:
Здравствуйте, 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 >>
Re: P/Invoke без использования DllImport
От: vdimas Россия  
Дата: 23.04.04 12:25
Оценка:
Здравствуйте, 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++, и сделать все одной строчкой, а не городить огороды на ровном месте, не правда ли?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.