Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.11.11;
Скачать: CL | DM;

Вниз

не могу правильно указать тип переменных для функций из одной DLL   Найти похожие ветки 

 
AlexVit ©   (2002-10-31 08:21) [0]

Я всех привествую!
Беда у меня такая: есть DLL-ка (arGCCsender.dll), написанная на С партнерами фирмы. Они оставили исходники. Вот текст заголовочного файла arGCCsender.h с функциями, которые меня интересуют:
#ifndef arGCCsender_H_INCL
#define arGCCsender_H_INCL
//-----------------------------------------------------------------------------
// Connect/reconnect to machine
extern "C" int argccsender_connect(const char *ip, int port);
// Disconnect
extern "C" int argccsender_disconnect(void);
// Send message to machine
extern "C" int argccsender_send(const char *type, const void *msg, int msglen);
//-----------------------------------------------------------------------------
#endif

я прописываю функции этой DLL в своей программке так:
function argccsender_connect(ip: PChar; port: Integer): integer; external "arGCCsender.dll";
function argccsender_disconnect: integer; external "arGCCsender.dll";
function argccsender_send(ttype: PChar; msg: PChar; msglen: Integer): integer; external "arGCCsender.dll";

А использую так:
...
Edit1.Text := IntToStr(argccsender_connect(PChar("127.0.0.1"), 9017));
...
Edit2.Text := IntToStr(argccsender_send(PChar("TEX"), PChar("123"), 3));
...
Edit3.Text := IntToStr(argccsender_disconnect)
Собственно, проблема вот в чем:
эти функции должны возвращать 0, если они отработали без ошибок. Однако, функции argccsender_connect и argccsender_send возвращают 3, т.е. возникает какая-то ошибка. Функция argccsender_disconnect возвращает 0, т.е. все ОК (и не удивительно, ведь она не имеет входных параметров!).
Подозреваю, что не правильно описал типы параметров, используемых теми двумя функциями. Правда, извращался и так и сяк, но ничего не добился. Вообщем, помогите, будьте добрыми, люди: что я делаю не правильно?

С уважением, AlexVit


 
Digitman ©   (2002-10-31 08:44) [1]

function argccsender_connect(ip: PChar; port: Integer): integer; cdecl; external "arGCCsender.dll";

function argccsender_disconnect: integer; cdecl; external "arGCCsender.dll";

function argccsender_send(ttype: PChar; msg: PChar; msglen: Integer): integer; cdecl; external "arGCCsender.dll";



 
Юрий Зотов ©   (2002-10-31 09:22) [2]

cdecl или stdcall?
Все же это DLL, там скорее stdcall использовано.


 
Lord Warlock ©   (2002-10-31 09:27) [3]

На паскале и С в экспортируемых функциях разный порядок параметров. Для устранения данной проблемы см
Digitman © (31.10.02 08:44)


 
Внук ©   (2002-10-31 09:32) [4]

>>Lord Warlock © (31.10.02 09:27)
Поскольку DLL предназначены для использования из программ, написанных на разных языках, и, в общем случае, заранее невозможно узнать, на чем писалась та или иная DLL, то грамотнее было бы применять в них соглашение stdcall, см. Юрий Зотов © (31.10.02 09:22)
То есть, все зависит от дальновидности авторов DLL :))


 
Digitman ©   (2002-10-31 09:47) [5]

Выдержка из хэлпа :

The cdecl convention is useful when you call functions from DLLs written in C or C++, while stdcall and safecall are used for Windows API calls

Хотя это и не 100%-гарантирует правильность сопряжения, все же думаю, что здесь нужен cdecl.

stdcall требует балансировку стека в теле вызываемой п/п, равно как и по-умолчанию в паскалевских п/п. Здесь же "тройка" осталась в стеке, ибо п/п скорее всего предполагает, что инструкция балансировки стека последует сразу за инструкцией вызова (т.е. в соответствии с cdecl-соглашениями), иначе - каким образом "тройка" могла пересечься с результатом ?

Впрочем выяснить это при желании можно элементарно, оттрассировав код вызова и тела п/п

И вот что мы там увидим :

В stdcall это будет выглядеть след.образом


push ..
push ..
...
push ...
call XXXX


где в теле XXXX возврат осущ-ся по RET N

В cdecl же это выглядит несколько иначе :


push ..
push ..
...
push ...
call XXXX
add esp, ...


где в теле XXXX возврат осущ-ся по RET




 
Lord Warlock ©   (2002-10-31 09:48) [6]

2 Юрий Зотов © (31.10.02 09:22)
2 Внук © (31.10.02 09:32)

Посмотрел у себя на подобное, Ваша правда.

ЗЫ 2 Внук © и нечего ржать :)


 
Alex4444444444   (2002-10-31 11:04) [7]

Pohozhe, extern "C" zadaet ih kak cdecl...


 
Digitman ©   (2002-10-31 11:40) [8]

>Alex4444444444

Далеко не всегда. Это - в зависимости от разработчика и версии компилятора.
В стародавние времена (например, в Quick C) директива extern "C" , кажется, и формировала код в соответствии с соглашениями, ныне "обзываемыми" cdecl. На тот момент устойчивого соглашения, именуемого сейчас как stdcall, как помнится, не фигурировало.
Так что самый надежный (даже в наст.время) способ при таких сомнениях (за неимением инф-ции о версии компилирующей среды ) - трассировка хотя бы одного из экспортируемых вызовов


 
AlexVit ©   (2002-10-31 16:47) [9]

Мужуки, спасибо всем большое, особенно Digitman!
Помогло cdecl. Все заработало. Как говорится, век живи - век учись.
Всем счастливо!!!


 
Digitman ©   (2002-10-31 16:58) [10]


> AlexVit



> Как говорится, век живи - век учись.


Чем мы тут, собссно, и занимаемся все).. я тоже учусь, в дан.случае - на твоем опыте)



Страницы: 1 вся ветка

Текущий архив: 2002.11.11;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
14-34192
Юрий Зотов
2002-10-21 18:17
2002.11.11
Поиск книги


1-34008
Anatoly P
2002-10-31 19:44
2002.11.11
TImage в файл


8-34135
DuMA
2002-07-21 15:58
2002.11.11
Как вывести изображение на время загрузки программы?


1-33972
beginner
2002-11-01 12:08
2002.11.11
Редактор математического текста


1-34084
liho26
2002-10-31 10:48
2002.11.11
Каретка возвращается!