73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
1

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

04.06.2013, 15:26. Показов 6088. Ответов 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
файл-то библиотеки находит, а функцию не видит

сборка выполняется следующей командой:
Код
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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.06.2013, 15:26
Ответы с готовыми решениями:

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

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

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

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

16
Ушел с форума
Эксперт С++
16449 / 7413 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
04.06.2013, 16:29 2
Единственный стопроцентно переносимый между различными компиляторами
способ 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  [ТС] 3
что-то все равно не понимаю

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

Эх, завтра на свежую голову буду разбираться
Спасибо
0
Ушел с форума
Эксперт С++
16449 / 7413 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
04.06.2013, 17:49 6
Просто добавьте "Module Definition File (def)" в проект.
А в нем объявите экспорты:
Код
LIBRARY "mylibrary.dll"

EXPORTS
    function1
    function2
    ...
0
502 / 351 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
04.06.2013, 18:17 7
Почитайте
http://www.willus.com/mingw/yongweiwu_stdcall.html
1
73 / 69 / 1
Регистрация: 19.05.2010
Сообщений: 167
05.06.2013, 10:15  [ТС] 8
Все равно ни в какую

Пробовал сделать преобразование согласно инструкции 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
Don't worry, be happy
17758 / 10526 / 2030
Регистрация: 27.09.2012
Сообщений: 26,502
Записей в блоге: 1
05.06.2013, 10:20 9
Цитата Сообщение от Kojt Посмотреть сообщение
вообще возможно ли осуществить затею?
Дональд Бокс - "Сущность технологии COM"
В книге рассматривается создание кода, который будет по минимуму зависть от транслятора.
1
Ушел с форума
Эксперт С++
16449 / 7413 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
05.06.2013, 10:33 10
Цитата Сообщение от 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  [ТС] 11
В ходе плясок с бубном была выявлена рабочая комбинация

В студии создаю 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 12
Зарегестрировался для чтобы чтобы отписаться в этой теме.
Надеюсь что некропостинг не нарушает правила

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

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

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

Я вижу самым логичным залесть в исходники boost_python и каким то образом добавить выше указанные алиасы, дабы удовлетворить и движок и мою DLL собранную GCC.
0
Ушел с форума
Эксперт С++
16449 / 7413 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
02.08.2015, 10:40 13
Dll может иметь два и более экспорта на одну и ту же функцию.
Например (DEF-файл):
Код
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 14
Есть ли какое то решение для такой проблемы?
Возможно прокси-библиотека?

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

Верно ли я понимаю?
0
Ушел с форума
Эксперт С++
16449 / 7413 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.08.2015, 08:59 17
Да. Может быть, есть еще какие-то способы, но это то, что лежит на
поверхности и точно будет работать, если правильно все сделать.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.08.2015, 08:59
Помогаю со студенческими работами здесь

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

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

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

Использование DLL, написанной на delphi
Есть DLL CscLink.dll, но описание к ней на delphi Так как в delphi &quot;0&quot;, пытаюсь использовать в C#....


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru