С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
1

Линковка

01.01.2021, 14:43. Показов 2154. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всех с наступившим новым годом!

У меня есть два проекта. Один проект в dll - DirectX 11 fraemwork, другой просто Win32 окно, которое использует dll для запуска fraemwork. Я явно что то делаю не так. У меня были ошибки линковки, в которых линковщик ругался, что не может найти конструкторы. Конструкторы были в cpp файлах, а в h были только определены. Хорошо, я переместил их в h файлы, но это вызывает цепочку следующих ошибок линковки и уже не конструкторов, а методов. Я явно что то не понимаю. Так же очень странно что при сборке dll библиотека собирается нормально, но пир запуске из другого проекта C++ не находится подключенная в dll хэдеры, хотя при запуске из C# никаких ошибок не возникает. Сейчас я просто добавил ссылки на директории где лежат хэдеры зависимостей, но это явно не правильно.

Если нужен проект, чтобы мне помочь, скажите, просто он очень большой. Может есть какие то стандартные вещи которые нужно сделать при подключении dll к исполняемой программе.
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.01.2021, 14:43
Ответы с готовыми решениями:

Статическая линковка
Всем привет. Я скомпилировал простую программу с помощью mingw64, набрав в консоли: У меня...

Статическая линковка
Появилась необходимость прилинковать статическую библиотеку (GLFW) к проекту на C++. Я подключил...

Статическая линковка
Добрый вечер. Прочитал что бы екзешка запускалась на любом компьютере нужно сделать статическую...

Линковка проекта.
Уважаемые профессионалы, ткните меня носом в ошибку. Есть некоторая программа с множеством функций...

13
374 / 317 / 65
Регистрация: 14.10.2014
Сообщений: 1,348
01.01.2021, 15:04 2
BaredJJ, Dll к проекту можно подключить вот так:

C++
1
2
3
4
5
#define IMPORT __declspec (dllimport) 
#pragma comment(lib,"Dll.lib") //Подключаем Triangle()
std::string  Triangle(std::string);
 
//далее в коде вызываем Triangle(string) в нужном месте
но DirectX 11 fraemwork чтоб просто Dll'кой подцепить? Чёт сомневаюсь... Дайрект нужно подлючать к самой среде разработки, прописывая пути до файлов с объявлениями (заголовочные) и определениями (это либо исходники, либо lib, либо Dll) - инструкций, как это сделать, если что полно
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
01.01.2021, 15:30  [ТС] 3
Да похоже он видит библиотеку, но вот какие то функции при линковать не может. Вначале я просто добавил в зависимости данную dll, сейчас сделал как вы сказали. Добавил в конфигурацию линковки данную либу и путь к ней, но ошибки снова те же самые.

DirectX рками написанный. По сути нужно просто запустить фраемворк и предать туда хэндлы окна, приложения и размеры ViewPort-а

Добавлено через 11 минут
Хотя если подключать только функции, то он не может их найти
Вот пример лога

Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "void __cdecl StartEngine(void)" (?StartEngine@@YAXXZ) referenced in function wWinMain Engine F:\Engine\DX11Engine\Engine\Engine\Source.obj 1
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
01.01.2021, 15:45 4
Цитата Сообщение от BaredJJ Посмотреть сообщение
Хорошо, я переместил их в h файлы
Этого делать не надо было.

Цитата Сообщение от BaredJJ Посмотреть сообщение
Может есть какие то стандартные вещи которые нужно сделать при подключении dll к исполняемой программе.
Тут скорее у вас DLL как-то не так написана. Вы классы и функции из DLL экспортируете? Соглашения о вызове и декорацию имен учитываете?
Какой у вас компилятор, какая разрядность получаемых приложения и DLL?

Все это должно быть согласовано, чтобы получилось.
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
01.01.2021, 16:19  [ТС] 5
Спасибо за ссылки. Ознакомлюсь, отпишусь тогда что не так если найду.
В кратце как я делал. Я создал хэдер в него добавил
C++
1
2
3
4
5
#ifdef GRAPHICSCORE_EXPORTS
    #define GRAPHICSCORE_API __declspec(dllexport)
#else
    #define GRAPHICSCORE_API  __declspec(dllimport)
#endif
И после создал функции для экспорта, которые используют классы в библиотеке.
C++
1
extern "C" GRAPHICSCORE_API void StartEngine();
Наверное я что то упустил. Почитаю, скажу )
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
06.01.2021, 15:05  [ТС] 6
Хммм, мне помогло добавление точной копии хэдера моей библиотеки в исполняемое приложение, я взял это из вот этой статьи https://docs.microsoft.com/ru-... w=msvc-160

У меня такое ощущение, что когда я до этого подключал dll и подключал хэдер, то использовалась не dll версия, а просто подключался хэдер и линковщик просто пытался разрешить конфликты.

Есть ли какой то способ, не делая копию хэдера библиотеки использовать библиотеку?
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
06.01.2021, 16:03 7
Цитата Сообщение от BaredJJ Посмотреть сообщение
Есть ли какой то способ, не делая копию хэдера библиотеки использовать библиотеку?
Не очень понятно зачем вы делали копию.

Обычно при разработке DLL создается интерфейсный заголовочный файл, в котором с помощью макроопределения (у вас это GRAPHICSCORE_EXPORTS) функции настраиваются на экспорт. Потом этот же заголовочный файл используется для подключения в основную программу, только на этот раз GRAPHICSCORE_EXPORTS не определяется, поэтому файл работает на импорт функций.
Естественно, надо еще подключить lib файл, чтобы линкер увидел функции.

Что из вышеописанного вы делали, или не делали?
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
06.01.2021, 16:29  [ТС] 8
Потом этот же заголовочный файл используется для подключения в основную программу, только на этот раз GRAPHICSCORE_EXPORTS не определяется, поэтому файл работает на импорт функций.
не совсем понятно, что значит GRAPHICSCORE_EXPORT не определяется? Под этим подразумевается просто использование функций в исполняемой программе? То да, я просто использовал функции. Пример ниже.
C++
1
2
3
4
5
6
if(InitialaizeEngine(hInstance, 1600, 900, WS_CAPTION | WS_MINIMIZE | WS_SYSMENU, hwnd))
    {
        StartEngine();
    }
 
    return 0;
Я подключал свою скомпилированную библиотеку в настройках проекта. Так же я настроил проект библиотеки на сборку в ту же директорию что и исполняемый файл, по этому он ищет библиотеку в директории проекта.

Я прикрепил скриншот структуры проекта. 1. Это папка сборки. 2. Это исполняемая программа. 3. Это dll.
Я подключал хэдер в исполняемую программу следующим образом:
C++
1
2
#define DLL_IMPORT __declspec (dllimport) 
#include "../GraphicsCore/GraphicsCore.h"
При таком варианте подключения исполняемая программа не может найти зависимости dll файлов, а при их ручном подключении, не может слинковать множество функций.

Так же я пробовал подключать функции отдельно
C++
1
2
3
#define DLL_IMPORT __declspec (dllimport) 
DLL_IMPORT bool InitialaizeEngine(HINSTANCE hInstance, int width, int height, DWORD wsStyle, HWND parent);
DLL_IMPORT void StartEngine();
В данном случае линковщик не может найти данные функции. Я думал что линковщик не видит библиотеку.

В примере что я добавил в прошлом посте, рекомендуют сделать хэдер с определением функций и подключить его в месте использования, я так и сделал и все заработало.
Миниатюры
Линковка  
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
06.01.2021, 16:52 9
Цитата Сообщение от BaredJJ Посмотреть сообщение
не совсем понятно, что значит GRAPHICSCORE_EXPORT не определяется?
В свойствах проекта DLL, т.е. при сборке самой DLL, должен быть определен макро GRAPHICSCORE_EXPORTS.
При сборке программы с этой DLL макро GRAPHICSCORE_EXPORTS не определяется.
В этом суть и предназначение вот этих строк:
Цитата Сообщение от BaredJJ Посмотреть сообщение
C++
1
2
3
4
5
#ifdef GRAPHICSCORE_EXPORTS
 #define GRAPHICSCORE_API __declspec(dllexport)
#else
 #define GRAPHICSCORE_API __declspec(dllimport)
#endif
Добавлено через 1 минуту
Цитата Сообщение от BaredJJ Посмотреть сообщение
#define DLL_IMPORT __declspec (dllimport)
Это неверно. Исходя из написанного выше.

Добавлено через 2 минуты
BaredJJ, Создание *.dll: для чего нужен компилятору параметр -DBUILD_DLL? (использую MinGW) (со второй страницы большая детализация)
Там много, но только потому, что приходилось долго рассказывать одно и то же.
Прочитайте. Тамошний BUILD_DLL - это ваш GRAPHICSCORE_EXPORTS.
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
06.01.2021, 17:12  [ТС] 10
Хорошо. Ознакомлюсь но уже не сегодня. В статье на MSDN что я кидал выше по поводу выбора импорта/экспорта сказано что это происходит автоматически при компиляции, по этому я и не придал этому значения.
Обратите внимание на операторы препроцессора в верхней части файла. Шаблон нового проекта для библиотеки DLL добавляет PROJECTNAME_EXPORTS к определенным макросам препроцессора. В этом примере Visual Studio определяет MATHLIBRARY_EXPORTS при сборке проекта библиотеки DLL MathLibrary.
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
06.01.2021, 17:18 11
Цитата Сообщение от BaredJJ Посмотреть сообщение
Обратите внимание на операторы препроцессора в верхней части файла. Шаблон нового проекта для библиотеки DLL добавляет PROJECTNAME_EXPORTS к определенным макросам препроцессора. В этом примере Visual Studio определяет MATHLIBRARY_EXPORTS при сборке проекта библиотеки DLL MathLibrary.
Об этом и речь.
Т.е. вручную прописывать
Цитата Сообщение от BaredJJ Посмотреть сообщение
#define DLL_IMPORT __declspec (dllimport)
не надо. Да оно у вас и неверно прописано было. Надо было так, судя по вашим постам выше:
C++
1
#define GRAPHICSCORE_API __declspec(dllimport)
Но это будет переопределение уже существующего макро. И это надо будет делать везде, перед каждым включением заголовочного файла в каждой единице трансляции. В общем, нехорошо.
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
07.01.2021, 18:07  [ТС] 12
Прочитал пост по импорту dll выше. Для чего использовать директивы препроцессора для выбора импорта или экспорта, все понятно и в принципе было понятно до этого. Так же я посмотрел приведенный вами пример по использованию функций из dll. Я думаю, что я что то упускаю. Если я пытаюсь подключить хэдер, как у вас в примере следующим образом
C++
1
#include <GraphicsCore.h>
то при сборке не находятся зависимости библиотеки
Если я объявляю импортируемые функции следующим образом
C++
1
2
extern "C" __declspec(dllimport) bool InitialaizeEngine(HINSTANCE hInstance, int width, int height, DWORD wsStyle, HWND parent);
extern "C" __declspec(dllimport) void StartEngine();
то все работает.

Давайте я еще раз расскажу что я сделал по порядку.
1. Я создал проект динамической библиотеки (GraphicsCore), который компилируется по пути ../x64/Debug
2. В dll препроцессором определил вариации импорта/экспорта функций.
3. В настройках проекта dll в поле ConfigurationProperties->C/C++ -> Preprocessor -> PreprocessorDefinitions указал макрос экспорта и скомпилировал библиотеку
4. Создал проект использующий библиотеку, который компилируется по пути ../x64/Debug
5. В настройках проекта ConfigurationProperties->linker->Input->AdditionalDependencies добавил GraphicsCore.lib
6. В настройках проекта ConfigurationProperties->C/C++ ->General->AdditionalIncludeDirectories указал путь до исходников GraphicsCore
7. В настройках проекта ConfigurationProperties->linker->General->AdditionalLibraryDirectories указал директорию сборки проекта
8. Подключил Хэдер в метсе использования директивой #include <GraphicsCore.h>

* В примере с путем приведен частный случай - ../x64/Debug , в действительности в проекте прописан путь сборки $(SolutionDir)$(Platform)\$(Configuration)\

Надеюсь описание моих шагов поможет пролить свет на проблему, так как довольно странно, что линковщик не может найти функции при отсутствии их объявления, как будто он просто не знает, что такая библиотека вообще есть.
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
07.01.2021, 18:54 13
Цитата Сообщение от BaredJJ Посмотреть сообщение
Если я объявляю импортируемые функции следующим образом
Зачем их объявлять? Они же есть (должны быть) в вашем заголовочном файле GraphicsCore.h. Или нет?

Цитата Сообщение от BaredJJ Посмотреть сообщение
Надеюсь описание моих шагов поможет пролить свет на проблему, так как довольно странно, что линковщик не может найти функции при отсутствии их объявления, как будто он просто не знает, что такая библиотека вообще есть.
По шагам все вроде правильно. Но вот где-то в деталях у вас несостыковка. Сделайте тестовый проект DLL с одной функцией по вашей собственной инструкции и тестовый проект, который подключает DLL и эту функцию использует. Проблема воспроизводится? Если да, то ничего не меняя, запаковываете эти тестовые проекты в архив и прикладываете сюда. Далее можно будет сказать в какой из деталей вы ошиблись.
0
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
07.01.2021, 19:00  [ТС] 14
Зачем их объявлять? Они же есть (должны быть) в вашем заголовочном файле GraphicsCore.h. Или нет?
Конечно объявлены.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//GraphicsCore.h
#pragma once
#include <Windows.h>
#include "Engine.h"
 
 
#ifdef GRAPHICSCORE_EXPORTS
    #define GRAPHICSCORE_API __declspec(dllexport)
#else
    #define GRAPHICSCORE_API  __declspec(dllimport)
#endif
 
Engine global_engine;
 
#ifdef __cplusplus
extern "C"{
#endif
 
GRAPHICSCORE_API bool InitialaizeEngine(HINSTANCE hInstance, int width, int height, DWORD wsStyle, HWND parent);
GRAPHICSCORE_API void StartEngine();
GRAPHICSCORE_API void StopEngine();
GRAPHICSCORE_API HWND GetEngineHwnd();
GRAPHICSCORE_API int GetWidth();
GRAPHICSCORE_API int GetHeight();
GRAPHICSCORE_API bool GetEnable();
 
    #ifdef __cplusplus
}
#endif
Я просто пытаюсь понять в чем проблема используя разные варианты подключения, так можно сузить варианты возможных проблем.

По шагам все вроде правильно. Но вот где-то в деталях у вас несостыковка. Сделайте тестовый проект DLL с одной функцией по вашей собственной инструкции и тестовый проект, который подключает DLL и эту функцию использует. Проблема воспроизводится? Если да, то ничего не меняя, запаковываете эти тестовые проекты в архив и прикладываете сюда. Далее можно будет сказать в какой из деталей вы ошиблись.
Хорошо, попробую, правда уже завтра. Сегодня к сожалению опять пора бежать.
0
07.01.2021, 19:00
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.01.2021, 19:00
Помогаю со студенческими работами здесь

Статическая линковка MinGW
Как задать статическую линковку для MinGW в среде Qt Creator? Прописал в pro- файле:, но не...

Правильная линковка библиотек
Долго искал в интернете, ничего толкового не нашёл, решил спросить тут. После создания приложения...

Линковка плюсового кода
Компилирую статическую библиотеку c++ для последующего ее включения в с-проект. Делаю так: ...

SFML, статическая линковка
Никак не получается соединить всё в один екзешник. -s добавил к библиотекам, SFML_STATIC...

Линковка библиотек в VS C++2010
Где то в параметрах проекта можно производить линковку библиотек к проекту. Кто нибудь знает где...

Линковка функций с emit
Доброе время суток. Друзья такой вопрос есть функция bool NETCore::send2ClientStr(QString...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
UserScript для подсветки кнопок языков программировани­­­я в зависимости от текущего раздела
volvo 13.01.2025
В результате работы этого скрипта подсвечиваются нужные кнопки не только в форм быстрого ответа, но и при редактировании сообщения: / / ==UserScript== / / @name CF_DefaultLangSelect / / . . .
Введение в модели и алгоритмы машинного обучения
InfoMaster 12.01.2025
Машинное обучение представляет собой одну из наиболее динамично развивающихся областей искусственного интеллекта, которая фокусируется на разработке алгоритмов и методов, позволяющих компьютерам. . .
Как на Python создать нейросеть для решения задач
InfoMaster 12.01.2025
В контексте стремительного развития современных технологий особое внимание уделяется таким инструментам, как нейросети. Эти структуры, вдохновленные биологическими нейронными сетями, используются для. . .
Как создать нейросеть для генерации картинок на Python
InfoMaster 12.01.2025
Генерация изображений с помощью искусственных нейронных сетей стала одним из наиболее захватывающих направлений в области компьютерного зрения и машинного обучения. В этой статье мы рассмотрим. . .
Создание нейросети для генерации текста на Python
InfoMaster 12.01.2025
Нейросети, или искусственные нейронные сети, представляют собой модели машинного обучения, вдохновленные работой человеческого мозга. Они состоят из множества взаимосвязанных узлов, или "нейронов",. . .
Как создать нейросеть распознавания изображений на Python
InfoMaster 12.01.2025
Введение в распознавание изображений с помощью нейросетей Распознавание изображений с помощью нейронных сетей стало одним из самых впечатляющих достижений в области искусственного интеллекта. Эта. . .
Основы искуственного интеллекта
InfoMaster 12.01.2025
Искусственный интеллект (ИИ) представляет собой одну из наиболее динамично развивающихся областей современной науки и технологий. В широком смысле под искусственным интеллектом понимается способность. . .
Python и нейросети
InfoMaster 12.01.2025
Искусственные нейронные сети стали неотъемлемой частью современных технологий, революционизировав множество областей - от медицинской диагностики до автономных транспортных средств. Python, благодаря. . .
Python в машинном обучении
InfoMaster 12.01.2025
Python стал неотъемлемой частью современного машинного обучения, завоевав позицию ведущего языка программирования в этой области. Его популярность обусловлена несколькими ключевыми факторами, которые. . .
Создание UI на Python с TKinter
InfoMaster 12.01.2025
TKinter — это одна из наиболее популярных библиотек для создания графических интерфейсов пользователей (GUI) в языке программирования Python. TKinter входит в стандартную библиотеку Python, что. . .
HTML5 в разработке мобильных приложений
InfoMaster 12.01.2025
Введение: Обзор роли HTML5 в мобильной разработке В современном мире мобильных технологий HTML5 стал ключевым инструментом для разработки кроссплатформенных приложений. Эта технология произвела. . .
Как создавать приложения для iOS/iPhone
InfoMaster 12.01.2025
Введение в разработку iOS-приложений Разработка приложений для iOS открывает огромные возможности в мире мобильных технологий. С каждым годом количество пользователей iPhone и iPad растет,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru