Форум программистов, компьютерный форум, киберфорум
Наши страницы

Создание *.dll: для чего нужен компилятору параметр -DBUILD_DLL? (использую MinGW) - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Работа с файлом типа fstream http://www.cyberforum.ru/cpp-beginners/thread1091503.html
Пишем несложный код: fstream file("Test.txt",ios_base::in|ios_base::app); int cnt = 0; while (cnt < 3) { cerr << char(file.get()); cnt++; }
C++ Эмулятор. На С, С++ Здравствуйте уважаемые читатели форума! У меня такой вопрос: (СРАЗУ ПРЕДУПРЕЖДАЮ Я НЕ ОЧЕНЬ ХОРОШО РАЗБИРАЮСЬ ПОКА В ЭТОМ ТАК ЧТО ОЧЕНЬ МНОГОЕ ИЗ МОИХ СЛОВ МОЖЕТ БЫТЬ ЖУТКИМ ....) В качестве... http://www.cyberforum.ru/cpp-beginners/thread1091494.html
C++ Использование стороннего CSP. Шифрование в программе
Снова обращаюсь к гуру программирования. Возникла ещё одна проблема, причём уже давно. Некоторые пользователи жалуются на невозможность использования программы по причине НЕсохранения их данных в...
Я создаю утечки памяти ! C++
Нет, я не хочу похвастаться этим. Я любитель использовать быстрые решение для того чтобы реализовать алгоритм или проверить "чтобы работало", но как известно нет ничего более вечного, чем...
C++ Каким образом идет поиск слов в кавычках? http://www.cyberforum.ru/cpp-beginners/thread1091483.html
Доброго времени суток! Вот вся программа #include <fstream> #include <iostream> #include <string> int main() { std::ofstream ofs("test.txt");
C++ Умножить матрицу 10х10 на вектор из 10 элементов дана матрица:10*10.умножить ее на вектор 10.помогите пожалуйста...очень нужно подробнее

Показать сообщение отдельно
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
21.02.2014, 11:08  [ТС]
Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//B.cpp
#include <windows.h>
#include <stdio.h>
 
void my_func_exe ();
extern "C" __declspec(dllimport) void my_func_dll_0 ();
extern "C" void my_func_dll_1 ();
 
int main () {
 my_func_exe ();
 my_func_exe ();
 my_func_dll_0 ();
 my_func_dll_0 ();
 my_func_dll_1 ();
 my_func_dll_1 ();
 return 0;
}
Командуем:
Bash
1
2
gcc -c B.cpp
objdump -d B.o
Наблюдаем B.o
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   e8 00 00 00 00          call   b <_main+0xb>
   b:   e8 00 00 00 00          call   10 <_main+0x10>
  10:   e8 00 00 00 00          call   15 <_main+0x15>
  15:   a1 00 00 00 00          mov    0x0,%eax
  1a:   ff d0                   call   *%eax
  1c:   a1 00 00 00 00          mov    0x0,%eax
  21:   ff d0                   call   *%eax
  23:   e8 00 00 00 00          call   28 <_main+0x28>
  28:   e8 00 00 00 00          call   2d <_main+0x2d>
  2d:   b8 00 00 00 00          mov    $0x0,%eax
  32:   c9                      leave
  33:   c3                      ret
Ну тут, собсно всё понятно. Если говорим компилятору __declspec(dllimport), то он вызывает функцию так:
Assembler
1
2
mov    eax, адрес_ячейки памяти_в_таблице_импорта // пока тут ноли
call   [eax]
В остальных случаях просто вызывает
Assembler
1
call   адрес_ячейки_памяти_в_коде_приложения //пока тут ноли
Синтаксис я переделал под masm.
Так, ну а потом линкёр заполняет таблицу импорта правильными адресами, вместо нолей подставляет нужные адреса, добавляет jmp во втором случае и всё становится круто.

Последний мой вопрос был: а почему компилятор во всех случаях, где функция вызывается из dll не пишет

mov eax, адрес_ячейки памяти_в_таблице_импорта // пока тут ноли
call [eax]

В свете последний осмыслений, этот вопрос кажется теперь глуповатым. "Потому, что компилятор не линкёр, так было задумано разработчиками."- этот ответ был бы вполне себе правомерным. Кесарю кесарево. Компилятор занимается тем, чем занимается, а линкёр адресами и различием того факта, откуда вызывается функция, не объявленная как- __declspec(dllimport). (Хотя в принципе, можно было сделать иначе, но это были бы дополнительные издержки- например, два прохода компилятора.)

Собсно, именно это и говорил DrOffset.

Для продвижения вперёд информации достаточно. А вообще по большому счёту, надо было бы знать- если компилятор лепит объектные файлы, то что такое объект в понимании компилятора? Максимально конкретно подойти к этому вопросу, и найти ответ типа:

1) Объектом в понимании компилятора является тело функции без адресов
2) и т. д.

Мысль, надеюсь понятна- что за сущности такие присутствуют в объектном файле ну и по адресам узнать. Но это отдельный разговор. Как и вопрос, возникший вследствие понимания- зачем нужны *.a файлы, если в них, кроме символов, ничего нет? Вопрос для отдельной темы, конечно. Всем спасибо.
1
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru