Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Один объектный файл для приложения (exe) и библиотеки (dll)

21K
10 января 2007 года
NWhisper
7 / / 10.01.2007
Всем привет! Встал интересный вопрос, можно ли так сделать на Visual C++?

Допустим, есть заголовочный файл:
//file1.h
 
Код:
class API App
{
public:
    void foo();
}


И есть исходник:
//file1.cpp
 
Код:
#define API
#include "file1.h"
void App::foo()
{}


После выполнения cl /MD file1.cpp получается файл file1.obj.

Далее, пишем еще один исходник:
//file2.cpp
 
Код:
#define API __declspec(dllexport)
#include "file1.h"


После сборки этого исходника командой cl /LD /MD file2.cpp /link file.obj появляется file2.dll, которая не экспортирует App::foo.

Может кто-нибудь сказать почему не экспортируется App::foo?
4.1K
10 января 2007 года
GRIENDERS
117 / / 06.06.2006
Ты пытаешься экспортировать целый класс, а не отдельную функцию.
Напиши __declspec(dllexport) void App::foo() {}
21K
15 января 2007 года
NWhisper
7 / / 10.01.2007
Цитата: GRIENDERS
Ты пытаешься экспортировать целый класс, а не отдельную функцию.
Напиши __declspec(dllexport) void App::foo() {}



Напиши, пожалуйста, полный текст исходника с изменениями... Че-т у меня ничего не получается :(

279
15 января 2007 года
bave
456 / / 07.03.2004
Не хочешь гемороя... - Не используй классы в dll
--------------------------------------------
void __declspec(dllexport) foo() {}
63
15 января 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: bave
Не хочешь гемороя... - Не используй классы в dll
--------------------------------------------
void __declspec(dllexport) foo() {}


Если конкретнее - то классы можно использовать без всяких проблем, если dll будет всегда грузится неявно. А если грузить явно - то придется класс "собирать" заново в исполняемом файле, т.к. из за борьбы с манглом придется переобъявить его заново.

21K
15 января 2007 года
NWhisper
7 / / 10.01.2007
Господа! Я не прошу рассуждать на темы, как можно по-другому это сделать... Как можно dll грузить и классы использовать я и так прекрасно знаю. Меня интересует только конкретный работающий пример, решающий мою задачу, указанную в первом посте :)
398
17 января 2007 года
Alexandoros
630 / / 21.10.2005
Цитата: NWhisper
Как можно dll грузить и классы использовать я и так прекрасно знаю.


Если знаеш зачем спрашиваеш????

Юзай или COM или откажись от этой дурацкой затеи.

21K
20 января 2007 года
NWhisper
7 / / 10.01.2007
Alexandоros, если Вам нечего сказать по существу вопроса, то и не надо вообще что-либо говорить. Если бы я знал, как решить указанный мной вопрос, я бы его тут и не задавал. Я прекрасно знаю, что существует миллион обходов, но меня интересует решение именно этой задачи, вам это ясно? Поэтому, если нет ответа, то проходите мимо, специалист.
63
20 января 2007 года
Zorkus
2.6K / / 04.11.2006
Если ты прекрасно знаешь, то зачем просишь написать тебе исходник весь?
А если хочешь чтоб его написали за тебя (это, по твоему, есть ответ по существу?), то пости в раздел Студентам.
21K
20 января 2007 года
NWhisper
7 / / 10.01.2007
Да уж, господа "эксперты" и "специалисты"... Вы эксперты воду в ступе толоч, наверное... Только один Grienders написал что-то по делу, все остальные только лясы тут точат, толку от вас нет. Я же говорю, мне тут не нужна философия малолетних, мне нужен конкретный пример, вот и все. Что тут не понятного?
562
21 января 2007 года
tarekon
175 / / 19.08.2003
А с какого бодуна эта функция должна экспортироваться?!?! У тебя есть один объектный файл, в котором определена эта функция и второй, в котором она якобы должна экспортироваться, но т.к. в file2.cpp определения этой функции нет, то нет и экспорта. Напиши определение и, скорее всего, получишь ошибку типа "multiple definition".
Другими словами, в файле file1.obj содержится реализация неэкспортируемой функции. В file2.obj нет ничего. В сумме - в DLL'ке - тоже ничего не экспортируется. Линкер вообще штука крайне тупая и если ты от него хочешь, чтобы он взял и сделал функцию экспортируемой, то ты слишком высокого о нём мнения.
Давай разберемся, чего же ты хочешь в итоге. Как следует из названия - один объектник для exe'шника и для dll'ки. Странное желание, но да ладно. В чем проблема сделать так, чтобы в экзешнике функции тоже были экспортируемые? Ничего страшного и сверхестественного в этом нет.
На вопрос я ответил. Если непонятно - могу попытаться другими словами объяснить. Изложи свою задачу и мы её решим.

P.S. И нефиг на экспертов наезжать.
P.P.S. Экспортирование класса эквивалентно экспортированию всех его функций. В этом примере экспортировался только operator= (). Не надо давать неправильных советов ;)
63
21 января 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: tarekon
в file2.cpp определения этой функции нет, то нет и экспорта. Напиши определение и, скорее всего, получишь ошибку типа "multiple definition".
Другими словами, в файле file1.obj содержится реализация неэкспортируемой функции. В file2.obj нет ничего. В сумме - в DLL'ке - тоже ничего не экспортируется. Линкер вообще штука крайне тупая и если ты от него хочешь, чтобы он взял и сделал функцию экспортируемой, то ты слишком высокого о нём мнения.


Так для того, чтоб его (линкер) "просвещать", и существуют ключи линковки, DEF -файлы и прочее:) А насчет проблем с multiple definion - заранее скажу, что часто это просто наглое вранье, и убирается установкой ключа /FORCE:MULTIPLE или еще более жестко, /FORCE.
Но чтобы их спокойно юзать, крайне рекомендую сначала почитать доки по линкеру..

21K
21 января 2007 года
NWhisper
7 / / 10.01.2007
Благодарю за ответы, господа!
562
22 января 2007 года
tarekon
175 / / 19.08.2003
Цитата: Zorkus
Так для того, чтоб его (линкер) "просвещать", и существуют ключи линковки, DEF -файлы и прочее:)


К прочему можно отнести и некоторые директивы #pragma, и тот самый dllexport. Прим. для интересующихся.

Цитата: Zorkus
А насчет проблем с multiple definion - заранее скажу, что часто это просто наглое вранье, и убирается установкой ключа /FORCE:MULTIPLE или еще более жестко, /FORCE.
Но чтобы их спокойно юзать, крайне рекомендую сначала почитать доки по линкеру..


А вот с этим не совсем согласен. Имхо, не должно возникать таких ошибок в нормально написанной программе. Или кто-то подскажет, как до этого дойти так, чтобы другого выхода из ситуации кроме /FORCE не было? У меня такое было только раз, когда я пытался прикрутить какую-то реализацию CORBA к MFC приложению. Проблема решилась выкидыванием из библиотеки CORBA нафиг ненужного там runtime'a.

63
22 января 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: tarekon
К прочему можно отнести и некоторые директивы #pragma, и тот самый dllexport. Прим. для интересующихся.


Да, конечно.

Цитата: tarekon

А вот с этим не совсем согласен. Имхо, не должно возникать таких ошибок в нормально написанной программе. Или кто-то подскажет, как до этого дойти так, чтобы другого выхода из ситуации кроме /FORCE не было? У меня такое было только раз, когда я пытался прикрутить какую-то реализацию CORBA к MFC приложению. Проблема решилась выкидыванием из библиотеки CORBA нафиг ненужного там runtime'a.


Ну я, конечно, не могу сказать, что в моей ситуации (там реализовывался перехват api подменой dll) это было единственное решение. Но я его использовал - и все стало работать, причем каких-либо багов не нашел ни я, ни тестер, ни препод, принимавший работу. Так что, возможно, следовало досконально разобраться, и написать такой код, чтобы работало без этого ключа, но я не стал:) Время поджимало, и, честно сказать, списал на "особенность" линкера в конце. Я сейчас не вспомню точно цитату из доков по ключам, но вроде бы, там про этот ключ написано было примерно так - "Убедитесь, что нигде нет мультиопределений. Если их, натурально, нет, а error есть - ну чтож, врубите этот ключ, и ошибка будет обойдена".
Подставляю голову под ваши мечи;)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог