Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];

Вниз

не могу правильно указать тип переменных для функций из одной 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.007 c
14-34215
ghg
2002-10-21 09:25
2002.11.11
Что программисты предпочитают читать?


3-33908
VikOss
2002-10-23 10:01
2002.11.11
Глюк в базе


3-33862
maras
2002-10-22 10:05
2002.11.11
Контекстный поиск в таблице


1-34042
From_X
2002-10-30 17:42
2002.11.11
И снова CGI


3-33877
irmantukas
2002-10-22 13:29
2002.11.11
Фильтр





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский