Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что за тип вызова "С", отличается от __cdecl 
V
    Опции темы
borisbn
Дата 13.7.2010, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



День добрый. Столкнулся с такой проблемой: имеется абстрактный интерфейс
Код

class IPackable {
    virtual char * CALL_TYPE serialize() = 0;
    virtual unsigned int CALL_TYPE size() = 0;
};

наследуюсь от него и реализую функции:
Код

class Pack : public IPackable {
    virtual char * CALL_TYPE serialize() { printf( "%p\n", this ); }
    virtual unsigned int CALL_TYPE size() { printf( "%p\n", this ); }
};

создаю dll-ку с одной функцией на M$-VC 2008, в которую передаю этот интерфейс
Код

void foo( IPackable * p ) {
    p->serialize();
}

создаю экземпляр Pack и передаю его в dll-ку
Код

Pack p;
printf( "%p\n", &p );
foo( &p );

теперь самое интересное: builder'овский и visul'овский printf'ы печатают разный this, если в настройках проекта builder'а в Project/Options/Advanced Compiler/Calling convention стоит "C", а в MSVC - __cdecl. Если же в явном виде прописать
Код

#define CALL_TYPE __cdecl 

то всё работает.
Подскажите, пожалуйста, что это за тип вызова "C" в Builder'е ?

Проблема усугубляется тем, что я не могу менять этот интерфейс, т.к. он уже используется в пол-сотне проектах.

Спасибо.

Это сообщение отредактировал(а) borisbn - 13.7.2010, 06:50


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 13.7.2010, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



это соглашения вызова для функций, если необходимо экспортировать функции из DLL для других разработчиков, делай стандартное соглашение вызова __stdcall, либо указывай сторонним разработчикам что они для вызова твоих функций должны использовать соглашение вызова __cdecl, хотя это не правильно. Это я к тому что не так давно мне пришлось прикручивать вызов своих функций как __fastcall - чисто борманавская реализация вызова, собственно хорошо что у меня был компилятор от бормана и я смог в исходнике задать тип вызова и откомпелировать код, еслибы у меня была только Visual Studio то я бы это сделать не смог бы.

Так что думай какую ты подл....ку сделаешь остальным.

Это сообщение отредактировал(а) Dem_max - 13.7.2010, 07:09


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
borisbn
Дата 13.7.2010, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Dem_max, 
1.
Цитата(borisbn @  13.7.2010,  06:46 Найти цитируемый пост)
Проблема усугубляется тем, что я не могу менять этот интерфейс, т.к. он уже используется в пол-сотне проектах.

2. В студии указан тип вызова __cdecl
3. (немного не в тему) в студии тоже есть __fastcall, но он отличается от builder'овского ( используются разные регистры )


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 13.7.2010, 07:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



Цитата

Проблема усугубляется тем, что я не могу менять этот интерфейс, т.к. он уже используется в пол-сотне проектах.

у тебя все равно все экспортируемые функции идут как CALL_TYPE так замени #define CALL_TYPE __cdecl  на #define CALL_TYPE __stdcall

если же у тебя 
Код

void foo( IPackable * p ) {
    p->serialize();
}


то экспортируй правильно
Код

void __stdcall foo( IPackable * p ) {
    p->serialize();
}



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
borisbn
Дата 13.7.2010, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Dem_max, дело в том, что CALL_TYPE я здесь специально добавил. в самом интерфейсе его нет, а менять интерфейс я никак не могу ( куча проектов уже использует dll-ки c этим интерфейсом ).
А функцию foo я просто так привёл. на самом деле у меня из visual'а экспортируется интерфейс, в котором все функции с явным типом вызова.

Проблема в том, что я никак не могу понять, что это за тип вызова в настройках builder'а ( Project/Options/Advanced Compiler/Calling convention ) "C" ?

P.S. 
Цитата(Dem_max @  13.7.2010,  06:56 Найти цитируемый пост)
делай стандартное соглашение вызова __stdcall

__stdcall, хоть и называется standard call не является таковым, т.к. для Си стандартным является __cdecl, мало того, в некоторых компиляторах он является единственным, и указать __stdcall нельзя.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 13.7.2010, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



Цитата

Проблема в том, что я никак не могу понять, что это за тип вызова в настройках builder'а ( Project/Options/Advanced Compiler/Calling convention ) "C" ?

Ах ты про это, да это __cdecl

Цитата

The Calling Convention options determine which calling sequences to generate for function calls. The C, Pascal, and Register calling conventions differ in the way each handles stack cleanup, order of parameters, case, and prefix of global identifiers.

Default = C

C tells the compiler to generate a C calling sequence for function calls (generate underbars, case sensitive, push parameters right to left, calling function cleans stack). This is the same as declaring all functions with the _ _cdecl keyword. Functions declared using the C calling convention can take a variable parameter list (the number of parameters does not need to be fixed).

You can use the _ _pascal, _ _fastcall, or _ _stdcall keywords to specifically declare a function using another calling convention.

Pascal tells the compiler to generate a Pascal calling sequence for function calls (do not generate underbars, all uppercase, pushes parameters left to right). This is the same as declaring all functions with the _ _pascal keyword. The resulting function calls are usually smaller and faster than those made with the C (-pc) calling convention. Functions must pass the correct number and type of arguments.

You can use the _ _cdecl, _ _fastcall, or _ _stdcall keywords to specifically declare a function using another calling convention.

Register forces the compiler to generate all functions using the Register parameter-passing convention, which is equivalent to declaring all functions with the _ _fastcall keyword. With this option enabled, functions or routines expect parameters to be passed in registers where possible.

You can use the _ _pascal, _ _cdecl, or _ _stdcall keywords to specifically declare a function using another calling convention.

Standard Call tells the compiler to generate a Stdcall calling sequence for function calls (does not generate underscores, preserve case, called function pops the stack, and pushes parameters right to left). This is the same as declaring all functions with the _ _stdcall keyword. Functions must pass the correct number and type of arguments.
    You can use the _ _cdecl, _ _pascal, or _ _fastcall keywords to specifically declare a function or subroutine using another calling convention.


Цитата

__stdcall, хоть и называется standard call не является таковым, т.к. для Си стандартным является __cdecl, мало того, в некоторых компиляторах он является единственным, и указать __stdcall нельзя.


Тогда те программы не смогут подгружать стандартные виндовозовские DLL 

Это сообщение отредактировал(а) Dem_max - 13.7.2010, 11:27


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
borisbn
Дата 13.7.2010, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Разобрался. Но только с Builder'ом. Он реабилитирован smile
Сделал следующее: в h-нике, который подключаю в студии явно указал тип вызова __cdecl, а в builder'е оставил без оного. И всё заработало правильно.
Странно, но в настройках проекта студии Project/Properties/C/C++/Advanced/Calling Convention стоит __cdecl (/Gd). Но это вопрос в другой форум.

P.S. 
Цитата(Dem_max @  13.7.2010,  11:23 Найти цитируемый пост)
Тогда те программы не смогут подгружать стандартные виндовозовские DLL 

А я не говорил о windows'овских компиляторах. g++ 4.1.2, например, не понимает. Но это тоже в другой форум smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0505 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.