Вызов двух функций с одинаковым именем из двух разных библиотек C
У меня есть две библиотеки C, к которым мне нужно получить доступ в том же исполняемом файле. У меня есть заголовочные файлы и .LIB файлы для обеих библиотек. К сожалению подмножество функций, которые мне надо иметь одинаковые имена. Лучшее решение, которое я смог придумать до сих пор, - использовать LoadLibrary для загрузки одной из библиотек DLL и явного вызова ее методов с помощью GetProcAddress. Есть ли способ для меня, чтобы неявно загрузить обе библиотеки и как-то дать компилятору подсказку, что в одном случае я хочу вызовите OpenApi в DLL A, а в другом случае я хочу вызвать OpenApi в DLL B?
Я разрабатываю исполняемый файл на C++ с помощью Visual Studio 2008 и соответствующей библиотеки времени выполнения C (msvcr90.файл DLL.)
[Edit]
комментатор Илья спрашивает ниже, что мне не нравится в решении GetProcAddress. Мне это не нравится по двум причинам:--1-->
- это делает код более сложным. Одна строка кода для вызова функции заменяется тремя строками кода, один чтобы определить сигнатуру функции, нужно вызвать GetProcAddress и фактически вызвать функцию.
- Он более склонен к ошибкам во время выполнения. Если я неправильно пишу имя функции или испорчу подпись, Я не вижу ошибки до времени выполнения. Скажем, я решил интегрировать новую версию dll, и одно из имен методов изменилось, оно будет компилироваться просто отлично и не будет иметь проблем до фактического вызова GetProcAddress, который может быть даже пропущен в тесте пройти.
3 ответов
раньше вы могли "переименовать" импортированный символ с помощью компоновщика .def файл. Возможно, ты все еще можешь ,но это было так давно.Def-файлы широко используются, трудно найти документацию.
в текущей документации MSDN директива IMPORTS указана как "зарезервированное ключевое слово". Я не уверен, что это означает, что они удалили функциональность, или если они просто не хотят ее больше поддерживать.
вот на странице, которая описывает импорт директива:
http://www.digitalmars.com/ctg/ctgDefFiles.html#imports
другие альтернативы kludgy:
создать функции-оболочки для конфликтующих API. Эти функции могут делать
LoadLibrary()/GetProcAddress()
танец. Все другие не конфликтующие функции могут быть неявно связаны как обычно. На самом деле, это решение, вероятно, наименее kludgy из 3 в этом ответе.создайте 2 библиотеки оболочки, такие, что каждая из них ссылается только на одну или другую библиотеку с конфликтующими именами. Используйте разные имена в библиотеках-оболочках, которые просто переходят к реальным библиотекам. Обратите внимание, что библиотекам - оболочкам не нужно обертывать все API-интерфейсы-им просто нужно обернуть конфликтующие.
вы можете создавать новые файлы библиотеки импорта, которые переименовывают соответствующие функции, а затем неявно связываются с обоими модулями DLL, используя эти новые библиотеки импорта. Вот статья базы знаний Майкрософт, описывающая этот процесс:Как создать 32-разрядные библиотеки импорта без .OBJs или Source.
мне удалось прийти к клуджи-альтернативе № 2 Майка Б (или № 3, если считать исходное предложение) после того, как я немного подумал над этим вопросом.
Это мой любимый из трех для моего конкретного случая потому что это, кажется, требует наименьшего объема работы и, вероятно, может быть наиболее очевидным для расшифровки кому-то новому, глядя на код. Я считаю, что я могу просто выполнить эти шаги и быть вверх и работает:
- использовать некоторые регулярное выражение magic и find / replace, чтобы превратить заголовочные файлы с вызовами функций, которые у меня есть в файл заголовка оболочки и файл реализации оболочки. (где каждый метод в dll-оболочке дифференцируется некоторым общим новым элементом имени, экономя мое время на сортировку конфликтов), поэтому FunctionCall () становится WrapperOneFunctionCall () и WrapperTwoFunctionCall () в каждой соответствующей dll-оболочке.
- связать dll-оболочку с соответствующей базой файл DLL.
- свяжите мой исполняемый файл с библиотеками-оболочками, удалите ссылки на базовые библиотеки DLL, но все равно включите определения констант, перечислений и структур, которые не нужно разрешать из базовой библиотеки dll (потому что мои функции-оболочки по-прежнему принимают те же типы параметров)
Если кто-то все еще читает эту тему, Мой следующий вопрос будет: "что-то не так с этим решением?"
спасибо респондентам за их помощь.