DLL-export, дикий затуп

Serab

Скажите, люди добрые, в этих наших виндовсах можно экспортировать из C++-библиотечки глобальную функцию без декорации имен (чтобы из другого языка подцепить, скажем с соглашением stdcall и не используя def-файл?
Да, компилятор - Visual C++ 2008

kokoc88

Скажите, люди добрые, в этих наших виндовсах можно экспортировать из C++-библиотечки глобальную функцию без декорации имен (чтобы из другого языка подцепить, скажем с соглашением stdcall и не используя def-файл?
Слабо понял вопрос, ты не про extern "C" спрашиваешь?

Serab

Слабо понял вопрос, ты не про extern "C" спрашиваешь?
Я спрашиваю: можно ли
1. Не используя def-файл
2. экспортировать C++-функцию
3. с недекорированным именем (без C++ или даже C-декорации)
4. с соглашением о вызове stdcall.
Что из этого непонятно?

kokoc88

4. с соглашением о вызове stdcall.
С этим соглашением - нельзя.

Serab

С этим соглашением - нельзя.
Этого ответа я и ждал =) Спасибо.

Serab

Уже написал сообщение, удалять не буду. Может кому пригодится в будущем.
Если написать
__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 нормально подцепится и стек не обрушит, но полагаться на это не рекомендется, естественно (потом добавим параметры и убьем себя).

Serab

А есть достоверная информация, почему?
Т.е. почему бы так не сделать?

kokoc88

А есть достоверная информация, почему?
Т.е. почему бы так не сделать?
При данном соглашении стек очищается вызванной функцией. Поэтому вызывающий должен знать размер.
Вся информация есть в 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: исправил ошибку в первом предложении.

Serab

При данном соглашении стек очищается вызывающим. Поэтому вызывающий должен знать размер.
В stdcall, естественно, очищает _вызываемый_, все написано в MSDN.
Это в cdecl очищает вызывающий (потому что может быть многоточие и только он знает сколько освобождать, т.е. сколько затолкнул, столько и доставать).
Если ты руководствовался этой логикой, то надо бы снова поправить название треда.

Serab

Короче, кто что там очищает вообще в этой задаче не важно, ведь если написать def-файл, то я могу вызвать хоть C++-ную функцию, просто создается синоним.
Мой вопрос в следующем: есть ли соответствующий синтаксис, чтобы не надо было создавать def-файл. И если нет, то почему, а если есть - то какой?

kokoc88

Если ты руководствовался этой логикой, то надо бы снова поправить название треда.
Нет, я руководствовался гуглом и ошибся в написании слова на русском языке.

Serab

Нет, я руководствовался гуглом и ошибся в написании слова на русском языке.
Ну кинь, плз, тогда ссылку где написано, что def-файл необходим, я не смог надыбать

Serab

ошибся в написании слова на русском языке
So lame. И в смысле слов следующего предложения ошибся

kokoc88

So lame. И в смысле слов следующего предложения ошибся
Найти ключевые слова для гугла - это будет твоё домашнее задание, so straight.
В смысле слов второго предложения я не ошибся.

Ivan8209

Я правильно понимаю, что от тебя зачем-то требуют что-то ещё
помимо прототипа?
---
...Я работаю антинаучным аферистом...

Serab

Я правильно понимаю, что от тебя зачем-то требуют что-то ещё
помимо прототипа?
Я не понял, что ты хотел сказать. Можешь ответить, что неясно вот в постановке вопроса?

Serab

Т.е. вопрос чисто технический, по поводу компилятора, никакой философии тут нету: он предоставляет мне возможность решить мою проблему одним способом (написать def-файл меня же интересует: можно ли избежать этого (могу описать причины если кому неясно, почему это отстой)?
Если да - то как, если нет - то почему?

Dasar

если нет - то почему?
никому это не надо, т.к. технология устаревшая(?)...

Serab

никому это не надо, т.к. технология устаревшая(?)...
Какая технология? Native C++ компилятор?

Dasar

Какая технология? Native C++ компилятор?
export статических функций из под dll

kokoc88

Если да - то как, если нет - то почему?
Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.

Serab

Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.
Тут речь о вызове? Т.е. невозможно из C вызвать недекорированный stdcall? Ты это хочешь сказать?

Dasar

Нет, потому что нету in-C-code возможности сделать недекорированный stdcall.
теоретически возможность есть - т.к. всего лишь надо передать определенные настройки линковщику, это можно сделать через тот же declspec

kokoc88

теоретически возможность есть - т.к. всего лишь надо передать определенные настройки линковщику, это можно сделать через тот же declspec
Так он этого и хочет.

Serab

export статических функций из под dll
Хм. Ты правда так думаешь? Т.е. я, конечно, все понимаю, .NET, все дела. Но Microsoft ведь не сдает старые технологии. Вон даже стандарт native C++ развивается.

Serab

Так он этого и хочет.
ДАААА! =)

Serab

Я даже по-другому скажу. Вот раньше не было __declspec вообще и надо было полюбому писать .def-файл. А вот когда добавляли __declspec почему не добавили в его синтаксис и этой возможности? Т.е. почему бы полностью не искоренить необходимость писать def-файл?

Serab

искоренить необходимость писать def-файл
все-таки напишу. Вот есть у меня несколько cpp-файлов в библиотеке. И захотел я один переместить в другую библиотеку. И надо следить, чтобы перекинуть соответствующие записи между def-файлами. Я думаю тут всем понятно, что это плохая ситуация.

Dasar

Хм. Ты правда так думаешь? Т.е. я, конечно, все понимаю, .NET, все дела. Но Microsoft ведь не сдает старые технологии. Вон даже стандарт native C++ развивается.
но COM тогда уж, но никак не static функции.
я пока с трудом представляю задачу, на которую хорошо ложатся static функции экспортированные из dll

Serab

но COM тогда уж, но никак не static функции.
я пока с трудом представляю задачу, на которую хорошо ложатся static функции экспортированные из dll
А что, мы уже перешагнули в эру благополучия, где в C++ нету глобальных переменных и функций?

Serab

static функции
глобальные ты имеешь в виду?
upd: понял, в частности static-функции классов.

Dasar

глобальные ты имеешь в виду?
upd: понял, в частности static-функции классов.
Да, все функции, что не объектные (что не методы)

Ivan8209

Я хочу понять, как это у вас странно работает компилятор.
У нас в таких случаях раньше делалась промежуточная выдача:

.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.
---
...Я работаю антинаучным аферистом...

Serab

Да, все функции, что не объектные (что не методы)
А как мы в век новых (не устаревших) технологий можем во время выполнения подгрузить библиотеку и создать экземпляр класса, описанного в ней, зная, скажем, его объявление?

Serab

У нас в таких случаях раньше делалась промежуточная выдача:
Мог бы хотя бы смысл того, что скрыто за тремя точками описать.

Serab

Мог бы хотя бы смысл того, что скрыто за тремя точками описать.
А, -S не заметил. Тогда ща подумаю. Но в винде такого не бывает, это точно =)

Dasar

А как мы в век новых (не устаревших) технологий можем во время выполнения подгрузить библиотеку и создать экземпляр класса, описанного в ней, зная, скажем, его объявление?
если (не устаревших) - то берем .net и вперед.
если все-таки устаревших технологий, то COM и вперед.
javascript, vb, vba, vbscript и т.д. именно так и загружают внешние объекты

Serab

если (не устаревших) - то берем .net и вперед.
если все-таки устаревших технологий, то COM и вперед.
javascript, vb, vba, vbscript и т.д. именно так и загружают внешние объекты
Не, с .NET-то все понятно =)
Я просто хотел понять, что ты называешь устаревшим. В этом треде обсуждаются, естественно, только native-средства, даже более точно, C++-библиотека, от которой ожидают определенный экспортируемый интерфейс. Тут все _предельно_ прозаично.

Serab

У нас в таких случаях раньше делалась промежуточная выдача:
Спасибо, код очень понравился. Только не совсем понятно, как он там отличит что надо экспортировать от того, что не надо?

Ivan8209

Смысл --- поправить нужные символы так, как тебе больше нравится,
поправлять удобнее в том формате, который показывает символы так,
как они будут в объектном файле.
---
"This user is BSD-compliant."

Serab

Хотя, немного подумав, можно допереть, что можно править все, не задумываясь.

Dasar

В этом треде обсуждаются, естественно, только native-средства, даже более точно, C++-библиотека, от которой ожидают определенный экспортируемый интерфейс.
т.е. даже без COM-а? а такое уж точно совсем устарело.
особенно если учесть, что рынок не понятен, т.к. клиентские приложения(те приложения которые и используют либы) скорее пишутся на всяких более простых языках, чем C++, а без поддержки com-а они все равно либу зацепить не смогут.

Ivan8209

> Только не совсем понятно, как он там отличит что надо
> экспортировать от того, что не надо?
Руками придётся писать.
Всё это может оказаться сложнее, чем твои ".def", если они работают.
---
"This user is BSD-compliant."

Serab

т.е. даже без COM-а? а такое уж точно совсем устарело.
особенно если учесть, что рынок не понятен, т.к. клиентские приложения(те приложения которые и используют либы) скорее пишутся на всяких более простых языках, чем C++, а без поддержки com-а они все равно либу зацепить не смогут.
Ладно, рассмотрим частный случай: функция DllRegisterServer, которую хочет COM. Ее можно заэкспортить без def-файла, но только потому что она не принимает параметров. Для DllGetClassObject, как я понимаю, необходим def-файл. Так вот меня это вымораживает: вдруг я захочу переместить ее вместе с фабрикой в другой исходник. Это не противоречит духу COM, т.е. я "должен этого хотеть" =)

Dasar

Ладно, рассмотрим частный случай: функция DllRegisterServer, которую хочет COM. Ее можно заэкспортить без def-файла, но только потому что она не принимает параметров. Для DllGetClassObject, как я понимаю, необходим def-файл. Так вот меня это вымораживает: вдруг я захочу переместить ее вместе с фабрикой в другой исходник. Это не противоречит духу COM, т.е. я "должен этого хотеть" =)
так это обычно все делается автоматом: wizard + atl. зачем там это куда-то перемещать - мне и остальному миллиону мух непонятно.
т.е. да, я согласен, что было бы удобно.
но весомого круга заинтересованных лиц в этом я не вижу

Serab

но весомого круга заинтересованных лиц в этом я не вижу
Просто любопытство =)
Оставить комментарий
Имя или ник:
Комментарий: