DLL-export, дикий затуп
Скажите, люди добрые, в этих наших виндовсах можно экспортировать из C++-библиотечки глобальную функцию без декорации имен (чтобы из другого языка подцепить, скажем с соглашением stdcall и не используя def-файл?Слабо понял вопрос, ты не про extern "C" спрашиваешь?
Слабо понял вопрос, ты не про extern "C" спрашиваешь?Я спрашиваю: можно ли
1. Не используя def-файл
2. экспортировать C++-функцию
3. с недекорированным именем (без C++ или даже C-декорации)
4. с соглашением о вызове stdcall.
Что из этого непонятно?
4. с соглашением о вызове stdcall.С этим соглашением - нельзя.
С этим соглашением - нельзя.Этого ответа я и ждал =) Спасибо.
Если написать
__declspec(dllexport) void f;
будет C++-декорация
Если написать
extern "C" __declspec(dllexport) void f
будет C-декорация, но еще нормальный синоним без декорации, т.е. то, что мне и нужно, но функция будет сгенерирована с соглашением cdecl.
extern "C" __declspec(dllexport) void __stdcall f
будет C-декорация stdcall (0 в данном случае недекорированный синоним при этом не создается.
Другой вопрос, что если у функции нету параметров, то cdecl-объявленная функция из внешнего кода, ожидающего stdcall нормально подцепится и стек не обрушит, но полагаться на это не рекомендется, естественно (потом добавим параметры и убьем себя).
Т.е. почему бы так не сделать?
А есть достоверная информация, почему?При данном соглашении стек очищается вызванной функцией. Поэтому вызывающий должен знать размер.
Т.е. почему бы так не сделать?
Вся информация есть в MSDN:
An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: 12
Edit: исправил ошибку в первом предложении.
При данном соглашении стек очищается вызывающим. Поэтому вызывающий должен знать размер.В stdcall, естественно, очищает _вызываемый_, все написано в MSDN.
Это в cdecl очищает вызывающий (потому что может быть многоточие и только он знает сколько освобождать, т.е. сколько затолкнул, столько и доставать).
Если ты руководствовался этой логикой, то надо бы снова поправить название треда.
Мой вопрос в следующем: есть ли соответствующий синтаксис, чтобы не надо было создавать def-файл. И если нет, то почему, а если есть - то какой?
Если ты руководствовался этой логикой, то надо бы снова поправить название треда.Нет, я руководствовался гуглом и ошибся в написании слова на русском языке.
Нет, я руководствовался гуглом и ошибся в написании слова на русском языке.Ну кинь, плз, тогда ссылку где написано, что def-файл необходим, я не смог надыбать
ошибся в написании слова на русском языкеSo lame. И в смысле слов следующего предложения ошибся
So lame. И в смысле слов следующего предложения ошибсяНайти ключевые слова для гугла - это будет твоё домашнее задание, so straight.
В смысле слов второго предложения я не ошибся.
помимо прототипа?
---
...Я работаю антинаучным аферистом...
Я правильно понимаю, что от тебя зачем-то требуют что-то ещёЯ не понял, что ты хотел сказать. Можешь ответить, что неясно вот в постановке вопроса?
помимо прототипа?
Если да - то как, если нет - то почему?
если нет - то почему?никому это не надо, т.к. технология устаревшая(?)...
никому это не надо, т.к. технология устаревшая(?)...Какая технология? Native C++ компилятор?
Какая технология? Native C++ компилятор?export статических функций из под dll
Если да - то как, если нет - то почему?Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.
Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.Тут речь о вызове? Т.е. невозможно из C вызвать недекорированный stdcall? Ты это хочешь сказать?
Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.теоретически возможность есть - т.к. всего лишь надо передать определенные настройки линковщику, это можно сделать через тот же declspec
теоретически возможность есть - т.к. всего лишь надо передать определенные настройки линковщику, это можно сделать через тот же declspecТак он этого и хочет.
export статических функций из под dllХм. Ты правда так думаешь? Т.е. я, конечно, все понимаю, .NET, все дела. Но Microsoft ведь не сдает старые технологии. Вон даже стандарт native C++ развивается.
Так он этого и хочет.ДАААА! =)
Я даже по-другому скажу. Вот раньше не было __declspec вообще и надо было полюбому писать .def-файл. А вот когда добавляли __declspec почему не добавили в его синтаксис и этой возможности? Т.е. почему бы полностью не искоренить необходимость писать def-файл?
искоренить необходимость писать def-файлвсе-таки напишу. Вот есть у меня несколько cpp-файлов в библиотеке. И захотел я один переместить в другую библиотеку. И надо следить, чтобы перекинуть соответствующие записи между def-файлами. Я думаю тут всем понятно, что это плохая ситуация.
Хм. Ты правда так думаешь? Т.е. я, конечно, все понимаю, .NET, все дела. Но Microsoft ведь не сдает старые технологии. Вон даже стандарт native C++ развивается.но COM тогда уж, но никак не static функции.
я пока с трудом представляю задачу, на которую хорошо ложатся static функции экспортированные из dll
но COM тогда уж, но никак не static функции.А что, мы уже перешагнули в эру благополучия, где в C++ нету глобальных переменных и функций?
я пока с трудом представляю задачу, на которую хорошо ложатся static функции экспортированные из dll
static функцииглобальные ты имеешь в виду?
upd: понял, в частности static-функции классов.
глобальные ты имеешь в виду?Да, все функции, что не объектные (что не методы)
upd: понял, в частности static-функции классов.
У нас в таких случаях раньше делалась промежуточная выдача:
.SUFFIXES: .ss
.c.s:; $(CC) $(CFLAGS) $(CPPFLAGS) -S $(.IMPSRC)
.s.ss:; $(SED) -e ... $(.IMPSRC) > $(.TARGET)
.ss.o:; $(COMPILE.s) $(.IMPSRC)
$(OBJS): $(.PREFIX).ss
Видел подобное для старых lex/yacc.
---
...Я работаю антинаучным аферистом...
Да, все функции, что не объектные (что не методы)А как мы в век новых (не устаревших) технологий можем во время выполнения подгрузить библиотеку и создать экземпляр класса, описанного в ней, зная, скажем, его объявление?
У нас в таких случаях раньше делалась промежуточная выдача:Мог бы хотя бы смысл того, что скрыто за тремя точками описать.
Мог бы хотя бы смысл того, что скрыто за тремя точками описать.А, -S не заметил. Тогда ща подумаю. Но в винде такого не бывает, это точно =)
А как мы в век новых (не устаревших) технологий можем во время выполнения подгрузить библиотеку и создать экземпляр класса, описанного в ней, зная, скажем, его объявление?если (не устаревших) - то берем .net и вперед.
если все-таки устаревших технологий, то COM и вперед.
javascript, vb, vba, vbscript и т.д. именно так и загружают внешние объекты
если (не устаревших) - то берем .net и вперед.Не, с .NET-то все понятно =)
если все-таки устаревших технологий, то COM и вперед.
javascript, vb, vba, vbscript и т.д. именно так и загружают внешние объекты
Я просто хотел понять, что ты называешь устаревшим. В этом треде обсуждаются, естественно, только native-средства, даже более точно, C++-библиотека, от которой ожидают определенный экспортируемый интерфейс. Тут все _предельно_ прозаично.
У нас в таких случаях раньше делалась промежуточная выдача:Спасибо, код очень понравился. Только не совсем понятно, как он там отличит что надо экспортировать от того, что не надо?
поправлять удобнее в том формате, который показывает символы так,
как они будут в объектном файле.
---
"This user is BSD-compliant."
Хотя, немного подумав, можно допереть, что можно править все, не задумываясь.
В этом треде обсуждаются, естественно, только native-средства, даже более точно, C++-библиотека, от которой ожидают определенный экспортируемый интерфейс.т.е. даже без COM-а? а такое уж точно совсем устарело.
особенно если учесть, что рынок не понятен, т.к. клиентские приложения(те приложения которые и используют либы) скорее пишутся на всяких более простых языках, чем C++, а без поддержки com-а они все равно либу зацепить не смогут.
> экспортировать от того, что не надо?
Руками придётся писать.
Всё это может оказаться сложнее, чем твои ".def", если они работают.
---
"This user is BSD-compliant."
т.е. даже без COM-а? а такое уж точно совсем устарело.Ладно, рассмотрим частный случай: функция DllRegisterServer, которую хочет COM. Ее можно заэкспортить без def-файла, но только потому что она не принимает параметров. Для DllGetClassObject, как я понимаю, необходим def-файл. Так вот меня это вымораживает: вдруг я захочу переместить ее вместе с фабрикой в другой исходник. Это не противоречит духу COM, т.е. я "должен этого хотеть" =)
особенно если учесть, что рынок не понятен, т.к. клиентские приложения(те приложения которые и используют либы) скорее пишутся на всяких более простых языках, чем C++, а без поддержки com-а они все равно либу зацепить не смогут.
Ладно, рассмотрим частный случай: функция DllRegisterServer, которую хочет COM. Ее можно заэкспортить без def-файла, но только потому что она не принимает параметров. Для DllGetClassObject, как я понимаю, необходим def-файл. Так вот меня это вымораживает: вдруг я захочу переместить ее вместе с фабрикой в другой исходник. Это не противоречит духу COM, т.е. я "должен этого хотеть" =)так это обычно все делается автоматом: wizard + atl. зачем там это куда-то перемещать - мне и остальному миллиону мух непонятно.
т.е. да, я согласен, что было бы удобно.
но весомого круга заинтересованных лиц в этом я не вижу
но весомого круга заинтересованных лиц в этом я не вижуПросто любопытство =)
Оставить комментарий
Serab
Скажите, люди добрые, в этих наших виндовсах можно экспортировать из C++-библиотечки глобальную функцию без декорации имен (чтобы из другого языка подцепить, скажем с соглашением stdcall и не используя def-файл?Да, компилятор - Visual C++ 2008