Форум программистов, компьютерный форум, киберфорум
Наши страницы
Visual C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.95
UFO665
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121
#1

Вопрос о dll - Visual C++

13.04.2010, 20:11. Просмотров 5305. Ответов 6
Метки нет (Все метки)

Visual Studio 2008, проект MFC. Написан в Windows XP SP3 (x86). При запуске на Windows 7 (x86) не происходит ничего (shared dll), а при запуске со статическими dll возникает ошибка (формулировка вылетела из головы ). Установка vcredist_x86 не помогла. При просмотре в Тотал коммандере в списке dll есть dll с красным восклиц. знаком (означает missed dll) (скриншот прилагается). Может ли это быть причиной?
http://www.cyberforum.ru/visual-cpp/thread1664517.html
0
Миниатюры
Вопрос о dll  
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2010, 20:11
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Вопрос о dll (Visual C++):

Использование функций DLL из другой DLL
Ребята подскажите имеется hscli.DLL hscli.LIB и hscli.H , собираю свою...

Кто может поделиться файлами ogg.dll, vorbis.dll и vorbisfile.dll - 32-х и 64-битными версиями?
Движок перевожу на платформу Win64 и нужно, чтобы разрядность ЕХЕ и DLL...

Windows I/o без Kernel32.dll и Advapi32.dll
Добрый день. Необходимо в Windows XP SP3 распечатать в стандартный поток...

При компиляции DLL-проекта не создается DLL-ка
Добрый день. создал в Visual Studio 2010 проект C+= типа DLL. В файл...

Вопрос
объясните пожалуйста следующий "процесс" (не обладаю пока терминологией). в...

6
Alex5
1120 / 781 / 231
Регистрация: 12.04.2010
Сообщений: 2,007
13.04.2010, 20:33 #2
В папке C:\windows\system32 есть файл mfc90.dll ?
На той машине, где программа работает?
На той машине, где не запускается?
Что будет, если попробовать самому скопировать mfc90.dll, msvcr90.dll в ту же папку, где находится exe-файл приложения?
А какая ошибка в случае static library ?
0
UFO665
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121
13.04.2010, 21:43  [ТС] #3
Alex5,
на компе, где windows 7, в system32 только mfc80.dll. на той машине, где я делал проект (и где прога запускается) в system32 не могу пока сказать, завтра посмотрю, а в 3-х разных папках разные mfc90.dll (отличаются по размеру). папки: C:\WINDOWS\WinSxS\x86_Microsoft.VC90.MFC_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_a173767a (у других 2 папок отличаются только символы в конце). На компе с Win 7 таких папок нет (visual studio не установлена).
копировать mfc90.dll, msvcr90.dll не пробовал.
про ошибку со static dll завтра посмотрю и напишу.
0
CheshireCat
Эксперт С++
2907 / 1256 / 114
Регистрация: 27.05.2008
Сообщений: 3,451
13.04.2010, 22:34 #4
Проблема известная. Называется Manifest Hell :-) (что? Вы уже устали от DLL Hell? отлично, получите взамен новую версию от Microsoft - Manifest Hell!)

Поставь на целевой машине redist_x86, проблема будет снята раз и навсегда. Причем, обрати внимание! Версия этого редистрибьюта должна точно соответствовать той версии Студии, на которой ты собираешь приложение. Иначе - получишь снова ту же ошибку.
0
alex_x_x
бжни
2454 / 1660 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
13.04.2010, 22:47 #5
Цитата Сообщение от CheshireCat Посмотреть сообщение
Поставь на целевой машине redist_x86, проблема будет снята раз и навсегда. Причем, обрати внимание! Версия этого редистрибьюта должна точно соответствовать той версии Студии, на которой ты собираешь приложение. Иначе - получишь снова ту же ошибку.
да, самое дельное, что можно предложить, как оказалось сегодня, даже мультитредовая сборка иногда не спасает, наверно это связано с зависимостями из сторонних библиотек
0
CheshireCat
Эксперт С++
2907 / 1256 / 114
Регистрация: 27.05.2008
Сообщений: 3,451
14.04.2010, 09:23 #6
Лучший ответ Сообщение было отмечено как решение

Решение

Дело именно в зависимостях. Позволю себе процитировать замечательный пост Юрия Жмеренецкого на RSDN, очень подробно описывающий проблему:
DLL-Связывание. Поиск DLL. Манифесты.

От: Юрий Жмеренецкий ICQ 380412032
Дата: 30.09.09 15:20
Оценка: 55 (11)
Здравствуйте, Rakafon, Вы писали:

R>Так вот ... могу ли я в этот механизм внести свои изменения/дополнения ...?
Может быть с помощью манифестов ...? Ведь в манифестах прописывают инфу о том где искать CRT-шные DLL-ки,
какую версию Common Controls подгружать и так далее ... Но скока я не рыл по поводу манифестов, везде
инфа только о том как подключать Shared DLL типа msvcr**.dll, msvcp**.dll, atl**.dll, cmnctrls.dll,
настраивать security, и так далее, а вот толкового мануала о том, что за инфу вообще можно запихать в
манифест, как можно ссылаться там на сторонние DLL модули и пр., никак и нигде найти не могу ...
R>Я просто хочу чтоб все DLL приложения не располагались в одном каталоге, а были распределены по
логическим подпапкам, при этом понятно связывались с EXE статически, а не динамически, существовали в
единственном экземпляре каждая, не была засрана переменная Path и т.д.
R>Коллеги, не знаете как это можно забабахать? Можно ли это сделать с помощью манифестов?


Можно. Манифесты это только верхушка айсберга под названием isolated applications & side-by-side assemblies
(не путать со сборками дотнета). Это решение прдлагается MS для уменьшения конфликтов версий, избавления
от DLL-hell'а, и прочих подобных аспектов (в частности это замена механизма DLL/COM redirection).

Терминология:
Isolated application — это обычное приложение, которое 'изолировано' от возможных изменений каких-либо внешних
компонентов.
Side-by-side assembly (сборка) — один файл (обычная DLL, COM-сервер, библиотека типов) или группа файлов.
* Сборка может быть установлена как private — для использования только одним приложением. Такая сборка
устанавливается в папку с приложением.
* Сборка может быть установлена как shared — такие сборки хранятся в папке %windir%\WinSxS и доступны для
использования любыми приложениями. Shared сборка обязательно должда быть подписанной. Private сборка также
может быть подписана (но это не обязательно).

Манифесты соответственно делятся на два типа — манифесты для приложений (или компонентов) и манифесты для сборок.
Манифесты первого типа описывают (в том числе) зависимости от сборок. Манифесты второго типа описывают (в том числе)
содержимое сборок.

Для решения поставленной задачи нужно: собрать private сборку — сначала производится сборка всех компонентов,
в нашем случае это один dll-файл (пусть будет TestDLLStatic.dll) Компилируется как обычная dll-библиотека
(возможно она будет обладать своим манифестом, но это не важно).

Каждая сборка должна иметь имя, по которой ее можно идентифицировать. Этим именем так же будет названа папка,
в которой хранится содержимое сборки (в MSND есть описание алгоритма поиска сборок, там учитываются и другие
случаи, вроде название локали). Также нужен манифест для описания содержимого. Пусть именем будет 'MyDll',
тогда манифест может иметь следующую структуру:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable/>
<assemblyIdentity type="win32" name="MyDll" version="1.0.0.0" processorArchitecture="x86" />
<file name="TestDLLStatic.dll" />
</assembly>

Т.е. список файлов (их может быть несколько), имя, версия и т.п. Подробный список разрешенных атрибутов есть в MSDN.
Атрбут publicKeyToken отсутствует (это важно), т.к. сборку мы не будем подписывать.

Теперь структура папок:

TestDLLHost.exe (это приложение будет использовать нашу сборку)
MyDll - папка
|- MyDll.manifest - манифест, описанный выше
\- TestDLLStatic.dll

Название папки и файла-манифеста должны быть такими же как и атрибут 'name' используемый в манифесте.

Теперь о том как использовать эту сборку: для приложения TestDLLHost.exe должен существовать свой манифест, в
котором нужно указать завивимость от нашей сборки. Такой манифест может быть внешним (отдельный файл) или внедренным.
MS Visual Studio по умолчанию (правда не помню с какой версии) использует внедренный манифест — в таком случае можно
воспользоваться директивой 'pragma' (в cpp файле):

#pragma comment(linker, "\"/manifestdependency:type='Win32' name='MyDll' version='1.0.0.0' processorArchitecture='X86'\"")

Это приведет к тому что в секцию dependency/dependentAssembly получившегося манифеста будет добавлена зависимость от
собрки MyDll:

<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='MyDll' version='1.0.0.0' processorArchitecture='x86' />
</dependentAssembly>
</dependency>

Важно — требуется полное совпадение атрибутов, используемых в 'pragma' и атрибутов в сборке, т.е.
type/version/processorArchitecture. Если автоматическая генерация манифестов выключена и используется внешний манифест,
то в него необходимо добавать секцию dependency вручную. Все.

Hint: Файлы из MSVC CRT инсталлируются в качестве shared сборки, но ее можно превратить в private и носить с собой
(release версию) — таким образом не нужно при установке проверять наличие соответствующей версии (и устанавливать в
случае необходимости). Как это делается: В папку с приложением копируется папка из (например)
'<X>:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86' — 'Microsoft.VC90.CRT':

TestDLLHost.exe
Microsoft.VC90.CRT (папка)
|- msvcm90.dll
|- msvcp90.dll
|- msvcr90.dll
\- Microsoft.VC90.CRT.manifest

После этого в файле 'Microsoft.VC90.CRT.manifest' необходимо удалить атрибут publicKeyToken. После чего на нее нужно
сослаться из манифеста приложения, добавив секцию dependency/dependentAssembly (но уже без атрибута publicKeyToken).

Но нужно понимать, что если приложение будет иcпользовать другую dll и эта dll будет использовать CRT из shared сборки,
то фактически в процессе окажется две копии runtim'a со всеми вытекающими последствиями.

-------------------------------------------------------------------------------------------------------------------------
Насчёт того, чтобы таскать CRT, ATL и другие части redist'а с собой ...
Один коллега в сообщении "Side-by-side assemblies и их проблемы" своём журнале указал на файлик redist.txt, который
располагается в корне инсталляции Visual Studio, например "%PROGRAMFILES%\Microsoft Visual Studio 8\redist.txt" или
"%PROGRAMFILES%\Microsoft Visual Studio 9.0\redist.txt".

Кроме прочего, в этом файле написано:

Visual C++ Runtime files

Subject to the license terms for the software, you may redistribute the .EXE files (unmodified) listed below.
These files can be run as prerequisites during installation.

vcredist_x86.exe
vcredist_x64.exe
vcredist_IA64.exe

For your convenience, we have provided the following folders for use when redistributing VC++ runtime files.
Subject to the license terms for the software, you may redistribute the folder (unmodified) in the application
local folder as a sub-folder with no change to the folder name. You may also redistribute all the files (*.dll
and *.manifest) within a folder, listed below the folder for your convenience, as an entire set.

\VC\redist\x86\Microsoft.VC90.ATL\
atl90.dll
Microsoft.VC90.ATL.manifest

\VC\redist\x86\Microsoft.VC90.CRT\
msvcm90.dll
msvcp90.dll
msvcr90.dll
Microsoft.VC90.CRT.manifest


Ключевое слово "unmodified".
То есть получается, что "удалить атрибут publicKeyToken" — не есть правомерно. А это значит, что сделать PRIVATE
сборку из Microsoft.VC90.CRT легально нельзя!
Я прав?
-----------------------------------------------------------------------------------------------------------------------
3
UFO665
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121
15.04.2010, 19:41  [ТС] #7
Цитата Сообщение от UFO665 Посмотреть сообщение
про ошибку со static dll завтра посмотрю и напишу.
С того момента, как я последний раз удачно линковал статически, я добавил 1 компонент. Теперь почему-то при статической линковке пишет: error LNK2001: unresolved external symbol ... как раз в той библиотеке, которую я добавил (ChilkatRel.lib). Версия ChilkatRelDll.lib для shared dll работает нормально.

Цитата Сообщение от CheshireCat Посмотреть сообщение
Поставь на целевой машине redist_x86, проблема будет снята раз и навсегда. Причем, обрати внимание! Версия этого редистрибьюта должна точно соответствовать той версии Студии, на которой ты собираешь приложение. Иначе - получишь снова ту же ошибку.
Проект создан в Visual Studio 2008 SP1. Ставил как раз redist_x86 для sp1. Эффект нулевой.
За цитату спасибо.

Добавлено через 23 часа 47 минут
Нашел причину, из-за которой не запускалось. У меня используется компонент vsflexgrid. Надо в system32 засунуть vsflex8l.ocx и через regsvr32.exe зарегистрировать. Сейчас все работает.
0
15.04.2010, 19:41
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.04.2010, 19:41
Привет! Вот еще темы с решениями:

вопрос
Есть код программы , в конце программы должен запрашеватся вопрос , продолжить...

вопрос по DLL
стоит следующая задача- функция в DLL выполняет цикл. нужно в основную...

Вопрос по DLL
Здравствуйте. Вопрос в следующим.Я создаю в солюшене Dll, потом в проекте в...

Вопрос dll
Возник такой вопрос: Как из dll библиотеки возвратить в основную программу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru