Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Порядок передачи параметров при вызове функции. / 25 сообщений из 68, страница 1 из 3
28.11.2018, 16:25
    #39739919
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Всем доброго времени суток!

Есть класс функции которого вызываются.
Изменяется порядок передачи параметров в зависимости от способа подключения библиотеки и типе возвращаемых данных.

Когда возвращаемое значение простой тип(int, char, указатель) или отсутствует(void) то все ок.

1)Когда возвращаемое значение объект класса то тут начинается неразбериха.
Если библиотека линкуется при сборке исполняемого модуля, то возвращаемый объект передается последним.
Код: plaintext
1.
2.
3.
4.
5.
6.
	Class->ParserFile();
000000013F2910D7  lea         rdx,[rsp+48h]  
000000013F2910DC  mov         rcx,qword ptr [Class]  
000000013F2910E1  call        qword ptr [__imp_Class::ParserFile (013F2EA3F8h)]  
000000013F2910E7  lea         rcx,[rsp+48h]  
000000013F2910EC  call        qword ptr [__imp_Result::~Result (013F2EA3B8h)] 



2)Если библиотека загружается по мере надобности и происходит вызов нужных функций, то возвращаемый объект передается первым.
Код: plaintext
1.
2.
3.
4.
5.
6.
		pFunction(Class);
000000013F911252  mov         rdx,qword ptr [Class] 
000000013F911257  lea         rcx,[rsp+68h]  
000000013F91125C  call        qword ptr [rsp+48h]  
000000013F911260  lea         rcx,[rsp+68h]  
000000013F911265  call        qword ptr [__imp_Result::~Result (013F96A3B8h)]  



Кто подскажет, как сделать так что бы параметры во втором случае передавались так же как в первом?
...
Рейтинг: 0 / 0
28.11.2018, 16:27
    #39739923
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
__cdecl
__stdcall
etc....

AFAIK
...
Рейтинг: 0 / 0
28.11.2018, 16:31
    #39739930
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Leonid Kudryavtsev,

Всё вызывается с __cdecl, но не помогает.
...
Рейтинг: 0 / 0
28.11.2018, 16:36
    #39739933
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Что такое "библиотека загружается по мере надобности" ?
...
Рейтинг: 0 / 0
28.11.2018, 17:21
    #39739974
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserВсё вызывается с __cdecl

Не вижу в приведённом ассемблере cdecl. В стэк ничего не заносится, после возврата стэк не
очищается. У тебя, походу, используется fastcall (что характерно для 64 бит).

Код объявления pFunction покажешь?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 17:29
    #39739978
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry SibiryakovКод объявления pFunction покажешь?


typedef Result (__cdecl *pFunction)(LPVOID);
...
Рейтинг: 0 / 0
28.11.2018, 18:01
    #39740004
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blondusertypedef Result (__cdecl *pFunction)(LPVOID);

В таком случае твоё "pFunction(Class)" это бред полный и работать не может, ибо ты
указатель на объект приводишь к указателю на функцию.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 18:06
    #39740007
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry Sibiryakovblondusertypedef Result (__cdecl *pFunction)(LPVOID);

В таком случае твоё "pFunction(Class)" это бред полный и работать не может, ибо ты
указатель на объект приводишь к указателю на функцию.


Я не привожу указатель на объект к указателю на функцию.
В функцию передаю указатель на объект и все прекрасно работает кроме описанного случая.
...
Рейтинг: 0 / 0
28.11.2018, 18:13
    #39740017
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserЯ не привожу указатель на объект к указателю на функцию.

pFunction это у тебя тип, объявленный с помощью typedef. Конструкция "тип(значение)" это
приведение типов, а не вызов функции. Так что где-то что-то ты недоговариваешь. Давай
полный код, а то ещё окажется, что у тебя pFunction() до кучи это метод класса, а в этом
случае приведённый ассемблер корректен, ибо метод получает this в rcx и первый параметр в rdx.

Или ты написал что-то неправильно и оптимизатор у тебя статическую функцию
Код: sql
1.
Result foo(bar*)


перековал в
Код: sql
1.
void foo(Result&, bar*)


в целях copy elimination.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 18:38
    #39740040
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry SibiryakovblonduserЯ не привожу указатель на объект к указателю на функцию.

pFunction это у тебя тип, объявленный с помощью typedef. Конструкция "тип(значение)" это
приведение типов, а не вызов функции. Так что где-то что-то ты недоговариваешь. Давай
полный код, а то ещё окажется, что у тебя pFunction() до кучи это метод класса , а в этом
случае приведённый ассемблер корректен, ибо метод получает this в rcx и первый параметр в rdx.


Да pFunction - это метод класса.
Об этом было сказано первой строкой в описание топика.

Ну, как то так.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        typedef Result (__cdecl *pFunction)(LPVOID);
	HMODULE hLibrary = LoadLibraryW(L"Library.dll");

	if(hLibrary != NULL)
	{
		pFunction pFunctionCall = (pFunction)GetProcAddress(hLibrary, MAKEINTRESOURCEA(616)); // ParserFile;
		
                pFunctionCall(this);
                ....
         }
...
Рейтинг: 0 / 0
28.11.2018, 19:11
    #39740063
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserДа pFunction - это метод класса.
Об этом было сказано первой строкой в описание топика.

Э, нет. ParserFile это метод, а pFunction это обычная функция. И не надо их путать.
Поставь принудительно -O0 и посмотри результат. Скорее всего будет такой же облом. А всё
потому, что не надо возвращать классы по значению из библиотечных функций.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 19:36
    #39740078
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry SibiryakovЭ, нет. ParserFile это метод, а pFunction это обычная функция. И не надо их путать.
Поставь принудительно -O0 и посмотри результат. Скорее всего будет такой же облом. А всё
потому, что не надо возвращать классы по значению из библиотечных функций.


Метод класса это функция, в которую первым параметром передается указатель на объект класса.
Остальное все уже описано выше.

Вопрос остался открытым.
...
Рейтинг: 0 / 0
28.11.2018, 19:48
    #39740083
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserМетод класса это функция, в которую первым параметром передается указатель на объект класса.

Да. А простая статическая функция это функция в которую может передаваться то, что хочет
компилятор, и так, как хочет компилятор. И в твоём случае компилятору хочется в pFunction
передать Result* для исполнения своего долга по copy elision.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 19:57
    #39740087
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry Sibiryakov,

К чему эмоции?

Повторю вопрос :
Кто подскажет, как сделать так что бы параметры во втором случае передавались так же как в первом?
Если без шаманства нельзя, то так и скажите что нельзя.

Спасибо.
...
Рейтинг: 0 / 0
28.11.2018, 19:59
    #39740088
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserКто подскажет, как сделать так что бы параметры во втором случае передавались так же как в
первом?

Измени прототип функции на
Код: sql
1.
void pFunction(LPVOID, Result&);


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 20:02
    #39740091
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry Sibiryakov,

Так она у меня уже работает.
Но хотелось, что бы без шаманства.
...
Рейтинг: 0 / 0
28.11.2018, 20:05
    #39740096
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
тогда повторю медленно: не надо из библиотечных функций возвращать классы по значению. И
по ссылке тоже лучше этого не делать. И вообще лучше DLL не использовать без особой нужды.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2018, 20:13
    #39740099
blonduser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Dimitry Sibiryakovтогда повторю медленно: не надо из библиотечных функций возвращать классы по значению. И
по ссылке тоже лучше этого не делать. И вообще лучше DLL не использовать без особой нужды.


Уже сделано и обратно не вернуть. Нужно использовать то что есть.
...
Рейтинг: 0 / 0
28.11.2018, 23:57
    #39740148
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Leonid Kudryavtsev__cdecl
__stdcall
в x64 этого нет
...
Рейтинг: 0 / 0
29.11.2018, 00:56
    #39740166
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserDimitry SibiryakovЭ, нет. ParserFile это метод, а pFunction это обычная функция. И не надо их путать.
Поставь принудительно -O0 и посмотри результат. Скорее всего будет такой же облом. А всё
потому, что не надо возвращать классы по значению из библиотечных функций.


Метод класса это функция, в которую первым параметром передается указатель на объект класса.
Остальное все уже описано выше.

Вопрос остался открытым.
не совсем так просто =)
...
Рейтинг: 0 / 0
29.11.2018, 00:57
    #39740167
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
судя по коду, [очередной] пользователь дибильдера
...
Рейтинг: 0 / 0
29.11.2018, 01:37
    #39740173
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduser,

blonduserЕсли библиотека линкуется при сборке исполняемого модуля, то возвращаемый объект передается последним.

blonduserЕсли библиотека загружается по мере надобности и происходит вызов нужных функций, то возвращаемый объект передается первым.
Способ линковки вообще не причем.
У вас разные вызовы синтаксически. В одном случае вы вызываете метод, в другом - свободную функцию.
Чтобы во втором случае тоже вызывалось как метод, вам нужно объявить указатель на метод, а не на функцию (при условии что в вашей DLL это действительно метод).

Ну и __cdecl убрать. Не надо указывать компилятору то в чем он лучше шарит ))

Код: plaintext
1.
2.
3.
4.
typedef Result (Class::*pFunction)(); 

pFunction pFunctionCall = (pFunction)GetProcAddress(hLibrary, MAKEINTRESOURCEA(616)); // ParserFile;
this->*pFunctionCall();
...
Рейтинг: 0 / 0
29.11.2018, 14:44
    #39740386
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
blonduserМетод класса это функция, в которую первым параметром передается указатель на объект класса.
Остальное все уже описано выше.
Вот совсем не обязательно, это одна из возможных реализаций. Компилятор может например указатель на объект передавать в метод через специальный регистр, который никогда для передачи обычных параметров не используется (и какая-то версия msvc именно так и делала).
...
Рейтинг: 0 / 0
29.11.2018, 14:47
    #39740387
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Anatoly Moskovsky
Код: plaintext
1.
2.
3.
4.
typedef Result (Class::*pFunction)(); 

pFunction pFunctionCall = (pFunction)GetProcAddress(hLibrary, MAKEINTRESOURCEA(616)); // ParserFile;
this->*pFunctionCall();

Не, так нельзя, указатель на метод - это не указатель на функцию, они не совместимы. У указателя на метод даже размер может отличаться от обычного указателя.
...
Рейтинг: 0 / 0
29.11.2018, 14:54
    #39740393
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Порядок передачи параметров при вызове функции.
Barlone,

Если функция невиртуальная, то указатель на нее тот же что и для свободных функций.

Виртуальные же вообще не надо импортировать из DLL напрямую . Они импортируются неявно через vtbl
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Порядок передачи параметров при вызове функции. / 25 сообщений из 68, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]