Упаковка сторонней DLL - PullRequest
       5

Упаковка сторонней DLL

1 голос
/ 23 апреля 2009

У меня есть сторонняя DLL, которая должна быть загружена динамически с помощью LoadLibrary () и которая использует соглашение о вызовах __cdecl. Мне нужно иметь возможность использовать dll из VB6, поэтому я создал собственную DLL-оболочку, которая использует соглашение о вызовах __stdcall и экспортирует необходимые функции.

Пришло дополнительное требование, и я изо всех сил пытаюсь понять, как управлять; обернутая DLL предоставляет API для другого приложения, и мне нужно одновременно подключиться к двум экземплярам приложения. Это проблема, так как DLL не имеет понятия сеанса, типичное взаимодействие будет выглядеть так:

tpc_connect("service1")
// Do some stuff
tpc_disconnect()

и что мне нужно сделать, это

session1 = tpc_connect("service1")
session2 = tpc_connect("service2")
// Do some stuff with session1
// Do some stuff with session2
tpc_disconnect(session1)
tpc_disconnect(session2)

Основная проблема, как я вижу, заключается в том, что один процесс может быть подключен только к одному сервису, поэтому первое решение, которое я попытался, - это перенести оболочку DLL в отдельный процесс путем создания сервера COM вне процесса используя ATL. Теперь у меня проблема в том, что я получаю только один экземпляр COM-сервера.

Итак, мои вопросы (наконец-то): есть ли способ заставить новый экземпляр COM-сервера ATL быть создан? Это лучший подход к проблеме или кто-то может придумать лучший способ решения этой проблемы.

Спасибо, Джексон

Ответы [ 2 ]

5 голосов
/ 23 апреля 2009

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

Поскольку файлы разные, Windows загрузит их все в отдельные адресные пространства и, таким образом, оставит их для вас отдельно.

Вот что я сделал:

  • Добавление функций в оболочку для создания и уничтожения экземпляров библиотеки.

  • Измените все остальные функции, чтобы получить указатель на экземпляр библиотеки, которую он использует.

  • В функции создания экземпляра сначала попытайтесь создать жесткую ссылку на исходную DLL-библиотеку, используя случайное имя файла (т.е. используйте CreateHardLink ). Если это не удастся, сделайте истинную копию DLL, используя случайное имя. Вам не нужно использовать расширение DLL, если вы не хотите. Динамически загружайте эту копию DLL и указатели на функции и возвращайте указатель на вашу внутреннюю структуру.

  • В функции уничтожения просто выгрузите DLL и удалите ее.

  • Лучше всего создать копию во временном каталоге, чтобы было очевидно, что она может быть удалена в случае сбоя, хотя я не уверен, есть ли ограничения в Vista и более поздних версиях для загрузки DLL из временного каталога. реж.

У меня все отлично работает.

1 голос
/ 23 апреля 2009

если вам нужно только 2 сеанса, вы можете сделать копию оригинальной библиотеки DLL и назвать ее как-нибудь еще. они в вашей dll-оболочке экспортируют два отдельных вызова (по одному для каждой dll). так что у вас будет:

session1 = tcp_connect("whatever")      'this points to dll1.dll
session2 = tcp_connect2("whatever")     'this points to a copy of dll1 called dll2.dll

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

-don

...