Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.61
Kojt
73 / 69 / 2
Регистрация: 19.05.2010
Сообщений: 167
04.06.2013, 15:26     Использование Dll написанной в VC++ в программе компилируемой MinGW #1
Добрый день!

Возникла следующая проблема.
Из-за некоторой специфики задачи (работа с 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 минуты
Уважаемый Модератор, мне кажется я ошибся с разделом и тему лучше переместить в "С++ для экспертов"
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.06.2013, 15:26     Использование Dll написанной в VC++ в программе компилируемой MinGW
Посмотрите здесь:

C++ Использование dll
Сохранение данных в написанной программе C++
Поиск записи в структуре - не могу найти ошибку в написанной программе C++
C++ MinGW. При запуске откомпилированной программы вылетает ошибка, что библиотека libgcc_s_dw2-1.dll отсутствует.
Создание *.dll: для чего нужен компилятору параметр -DBUILD_DLL? (использую MinGW) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
04.06.2013, 16:29     Использование Dll написанной в VC++ в программе компилируемой MinGW #2
Единственный стопроцентно переносимый между различными компиляторами
способ dll-экспорта в Win32 - это экспорт stdcall-функций с помощью def-файла.
Так сделан экспорт стандартных dll-ок Windows. Все остальное - это compiler-specific,
переносимость не гарантируется. Одни компиляторы (например, Visual C++ и
Intel C++ Compiler) хорошо совместимы друг с другом, другие нет.

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

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

Эх, завтра на свежую голову буду разбираться
Спасибо
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
04.06.2013, 17:49     Использование Dll написанной в VC++ в программе компилируемой MinGW #6
Просто добавьте "Module Definition File (def)" в проект.
А в нем объявите экспорты:
Код
LIBRARY "mylibrary.dll"

EXPORTS
    function1
    function2
    ...
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 928
Завершенные тесты: 1
04.06.2013, 18:17     Использование Dll написанной в VC++ в программе компилируемой MinGW #7
Почитайте
http://www.willus.com/mingw/yongweiwu_stdcall.html
Kojt
73 / 69 / 2
Регистрация: 19.05.2010
Сообщений: 167
05.06.2013, 10:15  [ТС]     Использование Dll написанной в VC++ в программе компилируемой MinGW #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" использовал, но результат один
Что я делаю не так и вообще возможно ли осуществить затею?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,869
Записей в блоге: 2
Завершенные тесты: 1
05.06.2013, 10:20     Использование Dll написанной в VC++ в программе компилируемой MinGW #9
Цитата Сообщение от Kojt Посмотреть сообщение
вообще возможно ли осуществить затею?
Дональд Бокс - "Сущность технологии COM"
В книге рассматривается создание кода, который будет по минимуму зависть от транслятора.
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
05.06.2013, 10:33     Использование Dll написанной в VC++ в программе компилируемой MinGW #10
Цитата Сообщение от Kojt Посмотреть сообщение
Что я делаю не так и вообще возможно ли осуществить затею?
Kojt, Вы должны понять, что экспорт из dll - вещь не стандартизированная.
Каждый компилятор волен искажать экспортируемые имена так, как ему вздумается.
И, соответственно, при импорте из dll он также будет ожидать совсем других имен,
нежели генерируются остальными компиляторами.

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

Поэтому про экспорт классов из dll забудьте, эта идея непереносимая.
Переносимо можно экспортировать из dll только функции, и только через def-файл, так
как это "родной" способ для Win32 подключения системных dll-библиотек, и все
Windows-совместимые компиляторы обязаны его поддерживать.
Kojt
73 / 69 / 2
Регистрация: 19.05.2010
Сообщений: 167
05.06.2013, 15:32  [ТС]     Использование Dll написанной в VC++ в программе компилируемой MinGW #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) не просто так закоменчен, когда он есть, то не работает связка.

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

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

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

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

Я вижу самым логичным залесть в исходники boost_python и каким то образом добавить выше указанные алиасы, дабы удовлетворить и движок и мою DLL собранную GCC.
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
02.08.2015, 10:40     Использование Dll написанной в VC++ в программе компилируемой MinGW #13
Dll может иметь два и более экспорта на одну и ту же функцию.
Например (DEF-файл):
Код
EXPORTS

SomeFunc
abcde?xyz_123 = SomeFunc
В первом случае (строка 3) SomeFunc экспортируется по своему "нормальному" имени.
Во втором случае (строка 4) в экспорте будет имя abcde?xyz_123.

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

Также все же возвращаясь к изначальной идее - Если к существующему набору экспортов я добавлю набор экспортов второго компилятора будет шанс что заработает?
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
02.08.2015, 15:44     Использование Dll написанной в VC++ в программе компилируемой MinGW #15
Решение таких проблем - это, как правило, либо C-шный интерфейс с
известными типами фиксированного размера и известного выравнивания,
либо использование технологии COM. Ну есть еще совместимые между
собой компиляторы, например MS C++ и Intel C++.
masaykh
1 / 1 / 0
Регистрация: 02.08.2015
Сообщений: 15
03.08.2015, 00:58     Использование Dll написанной в VC++ в программе компилируемой MinGW #16
Таким образом, не имея доступа к движку игры и имея дело с С++ у меня остается два варианта :
Либо создание прокси (который будет собран в MSVC) \ COM модуля.
Либо переписывание всех внешних функций на чистый Си.

Верно ли я понимаю?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2015, 08:59     Использование Dll написанной в VC++ в программе компилируемой MinGW
Еще ссылки по теме:

Сведение о программе написанной на с++ C++
Использование чужой dll в своей программе C++
C++ Использование dll в c++

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

Или воспользуйтесь поиском по форуму:
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
03.08.2015, 08:59     Использование Dll написанной в VC++ в программе компилируемой MinGW #17
Да. Может быть, есть еще какие-то способы, но это то, что лежит на
поверхности и точно будет работать, если правильно все сделать.
Yandex
Объявления
03.08.2015, 08:59     Использование Dll написанной в VC++ в программе компилируемой MinGW
Ответ Создать тему
Опции темы

Текущее время: 06:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru