Преобразование Windows Dll в .lib для C ++ Visual Studio 2008

Я знаю, что есть инструмент под названием Dll to lib, но разработчик просит 1000 долларов. Мне нужно преобразовать только одну библиотеку один раз, поэтому такую ​​цену нелегко оправдать.

Я пробовал IMPLIB32.EXE, но получаю только пустые файлы .lib. Как я могу этого добиться? Может быть, я смогу написать простое приложение для конвертации?

Добавлено1:

Dll обычно представляют собой stdcall, а не cdecl, и написаны на более старых языках C, например, НЕ C #, .NET или C ++. Теперь мне нужно вызвать их из приложений C ++. Примером может быть SQLite.dll или zlib.dll. У меня нет доступа к файлам .lib для этих dll.

Добавлено2:

Я переписал этот код для VS2008 http://floodyberry.wordpress.com/2008/09/08/generating-dll-wrappers/ и включает пример Dll и т. д., который можно загрузить здесь: http://www.transferbigfiles.com/Get.aspx?id=7d86fa0b-6ddc-4f6f-8d31-2c20824aae9a Это, в свою очередь, делает проект, который создает Dll. Когда я пытаюсь скомпилировать Dll, я получаю сообщение об ошибке компоновщика: AddShow.dll: фатальная ошибка LNK1107: недопустимый или поврежденный файл: не удается прочитать на 0x300 Описано здесь: http://list.isis.vanderbilt.edu/pipermail/udm-users/2006-March/000664.html Не знаю, как действовать. Видит око да зуб неймет

Далее мы переходим к этому методу

http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/

Запуск dumpbin с аргументом / exports C: \ path \ to \ AddShow.dll абсолютно ничего не делает После некоторых исследований

http://msdn.microsoft.com/en-us/library/aa446532.aspx кажется, что нужен mspdb71.dll (теперь mspdb80.dll) из папки common / ide dumpbin.exe теперь запускается с ошибкой:

фатальная ошибка LNK1106: недопустимый файл или диск заполнен: невозможно найти 0x6179A Эти потоки предполагают, что проблема может быть в версии dumpbin.exe

У меня Microsoft (R) COFF / PE Dumper Version 9.00.30729.01

Так что я безуспешно попробовал дампер двоичных файлов Microsoft (R) COFF версии 5.12.8078. После долгого чтения я не стал ближе

http://support.microsoft.com/kb/815645 http://support.microsoft.com/kb/839286 http://markmail.org/message/p5vwzyfyv3bs6z34 http://fixunix.com/programmer/94825-fatal-error-lnk1106-invalid-file-disk-full.html

Когда я запускаю ProcMon, я вижу первое появление queryopen и sqlite3.dll, когда svchost.exe пытается открыть его и терпит неудачу с ошибкой PATH NOT FOUND. путь - C: \ Program Files \ Microsoft Visual Studio 9.0 \ VC \ bin \ SQLITE3.DLL и является правильным. Если я помещаю его в корень диска C, я получаю ошибки NAME NOT FOUND:

C: \ Program Files \ Microsoft Visual Studio 9.0 \ VC \ bin \ link.exe. Локальный

C: \ Program Files \ Microsoft Visual Studio 9.0 \ VC \ bin \ dumpbin.exe. Локальный

из link.exe и dumpbin.exe соответственно. Я использую XPSP3, а не Vista, и это почти предел моих знаний о sysinternals. что это за файлы .local?

(csrss.exe также не может найти несколько файлов манифеста.)

Так что успеха еще нет, просто еще больше загадки

Добавлено 3:

Я попытался запустить dumpbin.exe из установленного места, \ Program Files \ Microsoft Visual Studio 8 \ VC \ bin, но ОС сообщила, что не может найти mspdb80.dll. Я скопировал mspdb80.dll из \ Program Files \ Microsoft Visual Studio 8 \ Common7 \ IDE, чтобы попытаться запустить dumpbin.exe.

теперь я получаю сообщение об ошибке: "Несоответствие менеджера баз данных программы c1902, пожалуйста, проверьте свою установку"

Если я удалю mspdb80.dll из \ Program Files \ Microsoft Visual Studio 8 \ VC \ bin, ошибка исчезнет! но я не могу запустить dumpbin.exe.

Добавлено 4:

Я наконец смог запустить dumpbin, скопировав следующие файлы в папку:

dumpbin.exe link.exe lib.exe mspdb80.dll

Я получил ошибку:

фатальная ошибка LNK1248: размер изображения (FFFFFXXX) превышает максимально допустимый размер (80000000)

один раз, но замена dll исправила это. Предположительно он испорчен?

Затем я перешел к следующему шагу в инструкциях: http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/ http://support.microsoft.com/kb/131313 и получил сообщение об ошибке: предупреждение lnk4017 не поддерживается для целевая платформа игнорируется. Оказывается, это потому, что я указал .dll вместо файла .def.

Полученные файлы .Lib и .exp затем добавляются в проект VS2008, компилируются и запускаются. Затем отладчик сообщил об ошибке: Ошибка проверки во время выполнения № 0 - значение ESP не было должным образом сохранено при вызове функции ...

Как упоминалось здесь Ошибка проверки во время выполнения № 0 - значение ESP не было должным образом сохранено при вызове функции после успешного обратного вызова C # из кода C ++ библиотеки GameSpy, это связано с тем, что я использовал stdcall в своей dll и объявил __cdecl в моем приложении.

extern "C" { // put Dll C function prototypes here
 int __cdecl AddTwoNum(int n, double f); // __stdcall
}

Так что изменение этого параметра на __stdcall должно исправить это, как вы думаете ... но, увы, нет.

теперь я получаю ошибку связывания: ошибка LNK2001: неразрешенный внешний символ _AddTwoNum @ 12

Это почему-то украшенное имя функции. Почему?

Добавлено n:

Оказалось, это потому, что файл .lib был создан с использованием dll с функциями STDCALL. STDCALL требует, чтобы вызывающий объект очистил стек, поэтому количество байтов аргументов добавляется к имени функции со знаком @. В этом случае у меня было три 4-байтовых целых числа, всего 12 байт.

Как только я переделал файл .lib из библиотеки DLL, созданной с помощью соглашения о вызовах CDECL, все стало хорошо.


person Community    schedule 08.10.2009    source источник
comment
Это собственная библиотека C / C ++ или .NET?   -  person Timo Geusch    schedule 08.10.2009
comment
Подождите ... Не было бы проще, по крайней мере, в случае zlib и sqlite3, получить исходные библиотеки импорта?   -  person Raphaël Saint-Pierre    schedule 09.10.2009
comment
sqlite - это просто пример, о котором все слышали. Я знаю, что для этого существуют исходные библиотеки inport, но dll, которую я пытаюсь преобразовать (AddTwoNum.dll), нет.   -  person Mike Trader    schedule 09.10.2009
comment
Я думаю, вам следует задать новый вопрос по поводу вашего обновления. Ему может быть полезно новое название и новый набор ответчиков.   -  person Raphaël Saint-Pierre    schedule 14.10.2009


Ответы (9)


Кажется, я не могу прокомментировать его ответ (мне нужно больше репутации?), Но вы можете попробовать использовать мой генератор оболочки. dll, чтобы создать заглушку .dll iain, предложенную.

person floodyberry    schedule 08.10.2009
comment
Спасибо за этот код. Я застрял на финише. см. выше - person Mike Trader; 09.10.2009
comment
Я нашел: social.msdn.microsoft .com / Forums / en / vcgeneral / thread / Вы ссылаетесь на .dll вместо .lib? - person floodyberry; 09.10.2009
comment
Аааа. Это была самая важная деталь, которой мне не хватало. Теперь это работает! Большое спасибо за код. - person Mike Trader; 10.10.2009
comment
Насколько я понимаю, новый проект dll фактически является оболочкой исходной dll, которая просто загружает ее динамически с помощью LoadLibrary () и GetProcAddress (), верно? - person Mike Trader; 10.10.2009
comment
да. Он разработан таким образом, чтобы вы могли легко создавать DLL-оболочки для перехвата / изменения вызовов, когда у вас нет доступа к источнику. например Оболочка ws2_32.dll для изменения сетевых вызовов, например, если вы хотите вручную регулировать работу приложения и т. Д. - person floodyberry; 10.10.2009
comment
Ах хорошо. Хотя это может сработать, на самом деле это не статическая загрузка. DLL-оболочка загружается статически, но фактический вызов dll im - нет, что является сутью этого вопроса. Thx tho. - person Mike Trader; 15.10.2009
comment
О, смысл связывания с оболочкой - просто заставить ее статически ссылаться на DLL. После того, как ваше приложение построено, вы просто заменяете DLL-оболочку исходной DLL, и она должна работать нормально (при условии, что она работает с оболочкой). - person floodyberry; 15.10.2009

Я предполагаю, что вы хотите вызвать некоторые функции / методы в dll на C / C ++, не имея доступа к файлу lib для связи с ним.

Если вы знаете подписи требуемых функций, вы можете:

  • создайте свою собственную версию dll-заглушки
  • создайте проект dll с тем же именем, что и dll, который вы хотите использовать
  • добавить реализации заглушек для функций, которые вы хотите вызвать
  • сигнатуры очень важны для проверки их совпадения.
  • затем напишите / соберите свою программу, чтобы связать ее с заглушкой dll
  • для запуска программы замените заглушку dll на настоящую
person iain    schedule 08.10.2009
comment
вы считаете правильным. Обычно у меня есть файл заголовка .h, поэтому я знаю подписи. Все описанные вами шаги для меня в новинку. Если бы вы могли их подробно описать или дать ссылку на демо, я был бы очень признателен. - person Mike Trader; 08.10.2009
comment
По сути, это сводится к созданию нового проекта DLL, который будет генерировать ту же библиотеку импорта, что и та, которую вам не хватает. - person Raphaël Saint-Pierre; 08.10.2009
comment
Верно. Это просто случай навигации по трудным водам, чтобы добраться туда. - person Mike Trader; 09.10.2009

Вы также можете пойти динамическим путем, используя LoadLibrary () и GetProcAddress ().

(См. Вторую ссылку для примера).

person Raphaël Saint-Pierre    schedule 08.10.2009
comment
Спасибо. Да, это всегда хороший способ. Это сработает, но цель этого вопроса - включить библиотеку в проект VS2008, не тратя 1000 долларов. - person Mike Trader; 09.10.2009

В таких случаях, как zlib или sqlite, вы можете напрямую загрузить исходный код и скомпилировать свой собственный файл lib. Фактически, я недавно сделал это для zlib, я загрузил исходный код с www.zlib .net (прямая загрузка zlib 1.2.3) открыл предоставленный файл проекта Visual Studio и скомпилировал как отладочную, так и выпускную версию библиотеки. Я не пробовал sqlite, но, видя, что у них есть исходники, это не должно быть трудным.

Если это проприетарная dll, вы можете попытаться попросить исходного разработчика или компанию предоставить файл lib, или написать свою собственную dll-заглушку, предложенную iain, или пойти по динамическому маршруту, который использовался RaphaelSP.

Если они экспортируются на C (без искажения имени C ++), я бы сам пошел по динамическому маршруту.

person Joshua    schedule 08.10.2009
comment
да. Dll, которые я хочу преобразовать, НЕ имеют файлов .def или .lib, доступных ТОЛЬКО в заголовке. - person Mike Trader; 09.10.2009

Я довольно быстро нашел этот пример: http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/

person Community    schedule 08.10.2009
comment
Спасибо. Я провел несколько часов, работая с dumpbin.exe, и мне не повезло. мои заметки выше - person Mike Trader; 09.10.2009

Это предположительно бесплатный инструмент для преобразования. Я не уверен, «бесплатно», как в «ограниченной пробной версии», или нет, информация не очень понятна. Если вы уже это тестировали, отредактируйте свой вопрос, и я удалю этот ответ.

person unwind    schedule 08.10.2009
comment
Вы были правы. Я предложил ему 100 долларов, и он согласился. Я предпочитаю иметь собственное решение. - person Mike Trader; 10.10.2009
comment
@Mike Trader - Разве ты не хочешь сказать, что я был прав, когда просил скидку? :) - person TWA; 10.10.2009

Если вы обратитесь к разработчику инструмента «Dll to lib», они могут предоставить вам скидку.

Я был в подобных ситуациях раньше (когда мне понадобился дорогой инструмент только один раз), и иногда мне удавалось получить большую скидку.

Никогда не помешает попробовать.

Удачи.

person TWA    schedule 08.10.2009
comment
Ты прав. Я сделал. Он принял за продукт 100 долларов, но, проделав такую ​​большую работу, я собираюсь сделать свой собственный. - person Mike Trader; 13.10.2009

Мне удалось получить библиотеку из DLL, используя подробности в http://wyw.dcweb.cn/dllfaq.htm. Ваш пробег может отличаться. Я использовал это, чтобы получить библиотеку из Python DLL для создания некоторых расширений Python, написанных на 'C'.

person Community    schedule 14.10.2009

Открытый исходный код edll имеет собственный внутренний загрузчик COFF. edll написан для совершенно разных целей, но поскольку он имеет независимый загрузчик COFF внутри, возможно, можно включить вашу .dll в двоичный поток или ресурс внутри вашего .exe, а затем во время выполнения использовать загрузчик COFF edll для загрузки встроенной dll .

person Community    schedule 05.01.2013