Страница 1 из 1

Параллельный вызов dll

Добавлено: 18 май 2020, 23:00
Juri
Tcp sniffer скачал когда-то с форума ni. Там dll обращается к winpcap. Все работает хорошо пока нет нужды обращаться одновременно к двум сетевым устройствам. Я эту проблему решил просто создав копию библиотеки dll с новым именем и теперь вызываю две одинаковых библиотеки параллельно. А может есть кошерный способ не городить копий?

Re: Параллельный вызов dll

Добавлено: 18 май 2020, 23:21
IvanLis
Usss писал(а): 18 май 2020, 23:00 А может есть кошерный способ не городить копий?
Я аналогичным образом делал, когда выполнял захват изображения с двух USB-Cam посредством DLL.

А что касается других способов, то мне кажется это от DLL зависит, если функции не поддерживают параллельный запуск, то наверное ничего и не получится, т.к. копии память поделить не смогу между собой.

Re: Параллельный вызов dll

Добавлено: 18 май 2020, 23:36
Artem.spb
"Поддерживаю предыдущего оратора"
У нас в отделе живут dll обоих типов. Если разработчик позаботился о параллельности, то работаем с одним экземпляром.
Если нет, то параллелим клонированием. Вплоть до того, что определяем количество процессоров в машине и программно создаём копии dll, а в реентрантную функцию передаём имя клона, с которым она уже работает.
Если у вас заранее известно количество копий, то можно так не заморачиваться.
Библиотеку качать лень. Но если там есть какой-то хэндлер вызова, то шансы на параллельность есть.

Re: Параллельный вызов dll

Добавлено: 19 май 2020, 08:25
dadreamer
From my perspective, WinPcap's binding adapters is designed to be reentrant, as no shared variables are used. And the NdisOpenAdapter function called by WinPcap should be reentrant too according to MSDN: https://msdn.microsoft.com/en-us/library/ee481122.aspx.
( https://seclists.org/nmap-dev/2015/q3/347 )
В большинстве случаев функции WinAPI реентерантны, если на MSDN явно не указано иначе. Функции WinPCap должны быть тоже, разработчики на это намекают: https://www.winpcap.org/pipermail/winpc ... 01674.html Остаётся только враппер lvwpcap.dll, т.к. внутри SubVI всё CLFN'ы уже жёлтые (Any Thread). Детально в исходник нет времени вникать, бегло посмотрел lvwpcap.cpp. В целом довольно неплохо написано, единственная глобальная переменная это pcap_if_t *gDevices. То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать. А что конкретно не работает?

Re: Параллельный вызов dll

Добавлено: 19 май 2020, 14:42
Juri
dadreamer писал(а): 19 май 2020, 08:25
From my perspective, WinPcap's binding adapters is designed to be reentrant, as no shared variables are used. And the NdisOpenAdapter function called by WinPcap should be reentrant too according to MSDN: https://msdn.microsoft.com/en-us/library/ee481122.aspx.
( https://seclists.org/nmap-dev/2015/q3/347 )
В большинстве случаев функции WinAPI реентерантны, если на MSDN явно не указано иначе. Функции WinPCap должны быть тоже, разработчики на это намекают: https://www.winpcap.org/pipermail/winpc ... 01674.html Остаётся только враппер lvwpcap.dll, т.к. внутри SubVI всё CLFN'ы уже жёлтые (Any Thread). Детально в исходник нет времени вникать, бегло посмотрел lvwpcap.cpp. В целом довольно неплохо написано, единственная глобальная переменная это pcap_if_t *gDevices. То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать. А что конкретно не работает?
Пример скачивал кажется от сюда https://forums.ni.com/t5/Example-Code/E ... anguage=en Все виайки класса сделал Preallocated.
На скрине я параллельно вызываю функцию определения списка текущих сетевых устройств. По идее рузельтат должен быть одинаков в обоих случаях. Но он разный. Тоже самое получается при вызове функции RadPacket. Пакеты приходят с потерями, либо вообще работает только одна копия vi

Re: Параллельный вызов dll

Добавлено: 19 май 2020, 14:58
IvanLis
dadreamer писал(а): 19 май 2020, 08:25То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать.
Попробуйте инициализацию и финализацию сделать одну на два потока.

Re: Параллельный вызов dll

Добавлено: 20 май 2020, 07:58
dadreamer
Usss, так пробовали?
IvanLis писал(а): 19 май 2020, 14:58Попробуйте инициализацию и финализацию сделать одну на два потока.

Re: Параллельный вызов dll

Добавлено: 20 май 2020, 12:48
Juri
IvanLis писал(а): 19 май 2020, 14:58
dadreamer писал(а): 19 май 2020, 08:25То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать.
Попробуйте инициализацию и финализацию сделать одну на два потока.
Спасибо! Это действительно сработало