Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/40: Рейтинг темы: голосов - 40, средняя оценка - 4.85
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167

Использование Dll написанной в VC++ в программе компилируемой MinGW

04.06.2013, 15:26. Показов 7764. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Возникла следующая проблема.
Из-за некоторой специфики задачи (работа с DirectShow) необходимо написать модуль (dll) в MSVC
и подцепить его к проекту на Qt (компилляция средствами MinGW)

Делаю для теста два простых проекта, без Qt

Проект Dll в MSVC:
dll.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
 
// This class is exported from the dll.dll
class DLL_API Cdll {
public:
    Cdll(void);
    // TODO: add your methods here.
};
 
extern DLL_API int ndll;
 
DLL_API int fndll(void);


dll.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// dll.cpp : Defines the exported functions for the DLL application.
 
#include "stdafx.h"
#include "dll.h"
 
 
// This is an example of an exported variable
DLL_API int ndll=0;
 
// This is an example of an exported function.
DLL_API int fndll(void)
{
    return 42;
}
 
// This is the constructor of a class that has been exported.
// see dll.h for the class definition
Cdll::Cdll()
{
    return;
}


И делаю проект в Qt (используется только qmake и MinGw)
dlltest.pro
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
 
SOURCES += main.cpp
 
INCLUDEPATH += dll
 
LIBS += ./debug/dll.lib
 
HEADERS += \
    dll/dll.h


main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include "dll/dll.h"
#include <iostream>
 
using namespace std;
 
int main()
{
    cout << "Hello World!" << fndll() << endl;
    return 0;
}


Библиотека собирается, но при сборке тестовой программы вываливается сообщение
undefined reference to `_imp___Z5fndllv'

Я уже всякие методы перепробовал, и reimp использовал, и dlltool для преобразования .lib
файл-то библиотеки находит, а функцию не видит

сборка выполняется следующей командой:
Code
1
g++ -Wl,-subsystem,console -mthreads -o debug/DllTest.exe debug/main.o  debug/dll.lib
Если открыть dll.lib в текстовом редакторе, то в нем есть вот такая запись __imp_?fndll@@YAHXZ
Может быть MS-компиллятор и MinGW по разному формируют имя функций для записи/чтения из dll ?

Подскажите что делать, куда копать?

Добавлено через 44 минуты
Уважаемый Модератор, мне кажется я ошибся с разделом и тему лучше переместить в "С++ для экспертов"
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.06.2013, 15:26
Ответы с готовыми решениями:

Использование чужой dll в своей программе
Есть dll-ка wavcarrier.dll. Её использует программа invisible secrets для шифрования файлов и связки их с wav файлом. Так вот, как можно...

Использование DLL написанной на C#
В силу обстоятельств требуется использовать функцию из DLL, написанной на C#. Пишу простенький тест - и не работает. Подскажите,...

Вызов программой, написанной на С++, функции из dll, написанной на Assembler (явное подключение dll)
Доброго времени суток!Задали лабораторную работу: программа, написанная на с++ должна подключать dll, написанную на Assembler и вызывать...

16
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.06.2013, 16:29
Единственный стопроцентно переносимый между различными компиляторами
способ dll-экспорта в Win32 - это экспорт stdcall-функций с помощью def-файла.
Так сделан экспорт стандартных dll-ок Windows. Все остальное - это compiler-specific,
переносимость не гарантируется. Одни компиляторы (например, Visual C++ и
Intel C++ Compiler) хорошо совместимы друг с другом, другие нет.

По теме: очень советую найти и прочесть книгу "C++. Практический подход к решению
проблем программирования" (М. Уилсон, английское название - "Imperfect C++").
Там есть глава "выживание в условиях реального мира", посвященная таким вот проблемам.
2
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
04.06.2013, 16:42  [ТС]
что-то все равно не понимаю

Уже совсем упростил
Объявляю функцию так:
C++
1
extern "C" int __stdcall fndll(void);
Но все равно вываливается ошибка
C++
1
 undefined reference to `fndll@0'
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.06.2013, 16:47
Visual C++ экспортирует функцию с такой сигнатурой, как "_fndll@0".
А MinGW "хочет" "fndll@0". Разница в ведущем подчеркивании.
Попробуйте сделать экспорт через def-файл (объявление функции не меняйте).
0
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
04.06.2013, 17:06  [ТС]
В настройках студии есть где-то пункт позволяющий создавать def-файлы?
Пробовал командой
Code
1
dlltool -D dll.dll -z dll.def --export-all-symbols
создать, но никаких имен в файле нет

Эх, завтра на свежую голову буду разбираться
Спасибо
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.06.2013, 17:49
Просто добавьте "Module Definition File (def)" в проект.
А в нем объявите экспорты:
Code
1
2
3
4
5
6
LIBRARY "mylibrary.dll"
 
EXPORTS
    function1
    function2
    ...
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
04.06.2013, 18:17
Почитайте
http://www.willus.com/mingw/yongweiwu_stdcall.html
1
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
05.06.2013, 10:15  [ТС]
Все равно ни в какую

Пробовал сделать преобразование согласно инструкции http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs

Скачал и gendef и pexports и reimp
Пробовал в разных комбинациях, а все равно ошибку пишет

gendef по dll генерирует вот такой def (команда <pexports msvc.dll | sed "s/^_//" > msvc.def> дает такой же результат, за исключением первой строки, имя библиотеки без кавычек)
LIBRARY "msvc.dll"
EXPORTS
??0Cmsvc@@QAE@XZ
??4Cmsvc@@QAEAAV0@ABV0@@Z ; has WINAPI (@4)
?fnmsvc@@YAHXZ
?nmsvc@@3HA DATA

при помощи программы dlltool из def и dll получается lib
Но не видит MinGW функций и все.

Я уже и __stdcall и export "C" использовал, но результат один
Что я делаю не так и вообще возможно ли осуществить затею?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
05.06.2013, 10:20
Цитата Сообщение от Kojt Посмотреть сообщение
вообще возможно ли осуществить затею?
Дональд Бокс - "Сущность технологии COM"
В книге рассматривается создание кода, который будет по минимуму зависть от транслятора.
1
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.06.2013, 10:33
Цитата Сообщение от Kojt Посмотреть сообщение
Что я делаю не так и вообще возможно ли осуществить затею?
Kojt, Вы должны понять, что экспорт из dll - вещь не стандартизированная.
Каждый компилятор волен искажать экспортируемые имена так, как ему вздумается.
И, соответственно, при импорте из dll он также будет ожидать совсем других имен,
нежели генерируются остальными компиляторами.

Даже если два разных компилятора имеют совместимый формат, это еще ни о чем не говорит.
Они могут использовать разные версии STL/Runtime, разные аллокаторы памяти и еще много
всего разного. Даже в пределах одной линейки компилятора возможны проблемы, если
используются разные его версии.

Поэтому про экспорт классов из dll забудьте, эта идея непереносимая.
Переносимо можно экспортировать из dll только функции, и только через def-файл, так
как это "родной" способ для Win32 подключения системных dll-библиотек, и все
Windows-совместимые компиляторы обязаны его поддерживать.
0
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
05.06.2013, 15:32  [ТС]
В ходе плясок с бубном была выявлена рабочая комбинация

В студии создаю Win32 Dll и в настройках проекта указываю путь такой, чтобы готовые .dll и .lib оказались рядом с .exe который создается MinGW
определяю функцию следующим образом:
dll.h
C++
1
2
3
4
5
6
7
#ifdef MSVC_EXPORTS
#define MSVC_API __declspec(dllexport)
#else
#define MSVC_API //__declspec(dllimport)
#endif
 
extern "C" MSVC_API int fnmsvc(void);


dll.cpp
C
1
2
3
4
5
6
7
#include "stdafx.h"
#include "dll.h"
 
MSVC_API int fnmsvc(void)
{
    return 42;
}


В проекте .pro добавляю INCLUDEPATH чтобы подключить dll.h и
LIBS += debug/dll.lib

В main.cpp указываю хэдер и вызываю нужную функцию.

Я уж было отчаялся и решил использовать явную загрузку dll при помощи класса QLibrary, и в хэлпе к нему наткнулся на то, как следует объявлять функцию, в случае импорта кусок __declspec(dllimport) не просто так закоменчен, когда он есть, то не работает связка.

Спасибо откликнувшимся за помощь!
Я правда так и не понял тонкостей декорирования имен функций в разных случаях, но хоть дело вперед сдвинулось.
0
1 / 1 / 1
Регистрация: 02.08.2015
Сообщений: 15
02.08.2015, 03:24
Зарегестрировался для чтобы чтобы отписаться в этой теме.
Надеюсь что некропостинг не нарушает правила

Столкнулся с аналогичной задачей :

тружусь над модификацией для игры, движок собран в MSVC, библиотеку модификации пытаюсь сделать при помощи mingw (игра сбрана достаточно старой версией MSVC в которой нет возможности использовать более новые оптимизации). Бибилиотека модификации использует boot_python в качестве интерфейса python-c++.
Суть проблемы в том что в boost_python имена функций такого типа :
?get_class_object@registration@converter @python@boost@@QBEPAU_typeobject@@XZ
а gcc ожидает :
_ZNK5boost6python9converter12registratio n16get_class_objectEv

У меня есть два варианта либо что-либо менять в самом dll модификации, либо же в boost_python.
Есть ли какой то вариант заставить функцию иметь два экспорта, аля алиас ?
Будет ли оно в таком формате адекватно работать?
И как это сделать?

Я вижу самым логичным залесть в исходники boost_python и каким то образом добавить выше указанные алиасы, дабы удовлетворить и движок и мою DLL собранную GCC.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.08.2015, 10:40
Dll может иметь два и более экспорта на одну и ту же функцию.
Например (DEF-файл):
Code
1
2
3
4
EXPORTS
 
SomeFunc
abcde?xyz_123 = SomeFunc
В первом случае (строка 3) SomeFunc экспортируется по своему "нормальному" имени.
Во втором случае (строка 4) в экспорте будет имя abcde?xyz_123.

Но в данном случае это все не имеет большого смысла.
Дело в том, что интерфейсы C++ не портируются, как правило, на другие
компиляторы, т.е. они не совместимы на двоичном уровне (нет ABI - Application
Binary Interface). Поэтому, если только речь не идет о простой функции,
возвращающей какой-нибудь int, работать это, скорее всего, не будет.
0
1 / 1 / 1
Регистрация: 02.08.2015
Сообщений: 15
02.08.2015, 13:32
Есть ли какое то решение для такой проблемы?
Возможно прокси-библиотека?

Также все же возвращаясь к изначальной идее - Если к существующему набору экспортов я добавлю набор экспортов второго компилятора будет шанс что заработает?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.08.2015, 15:44
Решение таких проблем - это, как правило, либо C-шный интерфейс с
известными типами фиксированного размера и известного выравнивания,
либо использование технологии COM. Ну есть еще совместимые между
собой компиляторы, например MS C++ и Intel C++.
0
1 / 1 / 1
Регистрация: 02.08.2015
Сообщений: 15
03.08.2015, 00:58
Таким образом, не имея доступа к движку игры и имея дело с С++ у меня остается два варианта :
Либо создание прокси (который будет собран в MSVC) \ COM модуля.
Либо переписывание всех внешних функций на чистый Си.

Верно ли я понимаю?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
03.08.2015, 08:59
Да. Может быть, есть еще какие-то способы, но это то, что лежит на
поверхности и точно будет работать, если правильно все сделать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.08.2015, 08:59
Помогаю со студенческими работами здесь

Использование DLL, написанной на C++, в C# (указатели)
Всем привет! Есть DLL, написанная на C++, в ней описана такая функция: int ReadData(int kpn,int bn,OUT DWORD*time,OUT...

Использование DLL написанной на С++ в Lazarus
Возник вопрос по использованию DLL написанной на С++ в Lazarus. Пример DLL на С++ *** MyDLL.h: *** #ifndef __MyDLL_H__ ...

Использование функций DLL, написанной на C++
В проекте C# нужно использовать функции, написанные на с++. Создал DLL-ку, все отлично цепляется. Вопрос в том, что в с++ проекте есть своя...

Использование dll, написанной на C++ Qt в Delphi
Добрый день, уважаемые форумчане. Работаю в команде разработчиков. Я пишу на С++Qt. Изначально главный разработчик писал программу...

Использование DLL, написанной на delphi
Есть DLL CscLink.dll, но описание к ней на delphi Так как в delphi &quot;0&quot;, пытаюсь использовать в C#. Ряд функци уже реализовал из...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru