Помогите разобраться с вызовом функции.
Есть длл-ка на Delphi, возникла трудность с вызовом именно одной функции, которая принимает в качестве параметров структуры.
{TParam - Входные данные следующей структуры:}type TParam = record
Cmd :Byte;
Sm :PChar;
Cr :PChar; {3+1 байт, если '', то по умолчанию}
Tr2 :PChar; {если '',то не учитывается, max 48 байт}
Add :PChar; {если nil или '', то не учитывается. Max 184 байт}end;
{TResult – Выходные данные следующей структуры:}type TResult = record
Cmd :Byte;
St :Byte;
Sm :PChar; {12+1 байт}
Cd :PChar; {max 48 байт}
Cr :PChar; {3+1 байт}
RN :PChar; {12+1 байт}
DT :PChar; {19+1 байт}
TI :PChar; {8+1 байт}
CN :PChar; {5+1 байт}
AC :PChar; {6+1 байт}
HC :PChar; {2+1 байт}
HT :PChar; {32+1 байт}
ED :PChar; {4+1 байт}TO :DWord;
TLV :PChar; {129+1 байт}end;
Function Func(p1:Byte; var p: TParam; var r: TResult) : Byte; stdcall;
typedef struct TResult {
...
char *Sm;
...
};
TResult r;
r.Sm = new char[13]; или malloc или чем пользуешьмя.
нужно объявлять в структурах указатели, а не массивы, ну и выделять память.
и еще нужно чтобы выравнивание структур в Delphi и C чтобы совпадало, по умолчанию в Delphi 4 (кажется). т.е. нужно в C сказать #pragma pack(4)
Здравствуйте, AlexFilan, Вы писали:
AF>Помогите разобраться с вызовом функции. AF>Есть длл-ка на Delphi, возникла трудность с вызовом именно одной функции, которая принимает в качестве параметров структуры.
AF>[pascal] AF>{TParam — Входные данные следующей структуры:} AF>type TParam = record AF> Cmd :Byte; AF> Sm :PChar;
Я лет 10 не писал на Delphi, но сдается мне, что PChar — это не массив, а указатель, то есть char*
Из этого следует, что в С++ все PChar надо заменить на char*. Входным присвоить значения. Выходным должна паскалевская функция присвоить значения. Кто удалять будет эти строки в Паскале и когда — твоя проблема
Но это еще не все.
Есть такое понятие — выравнивание. Из-за него Cmd имеет смещение в структуре 0, а Sm — отнюдь не 1, а 4. Можно, впрочем, сделать, чтобы была 1
#pragma pack(push)
#pragma pack(1)
// здесь все структуры, для которых это надо
#pragma pack(pop)
// восстановлен стандартный режим
Проблема в том, что выравнивание нужно сделать не на 1, а на то же значение, которое в Паскале, а какое оно там — я не знаю.
Здравствуйте, AlexFilan, Вы писали:
AF>Помогите разобраться с вызовом функции. AF>Есть длл-ка на Delphi, возникла трудность с вызовом именно одной функции, которая принимает в качестве параметров структуры.
AF>
AF>Function Func(p1:Byte; var p: TParam; var r: TResult) : Byte; stdcall;
AF>
Разница между вариантами А и Б в способе вызова. В случае А — код можно оставить без изменений, а в случае Б — придётся взять адрес (как, собственное, и делается для третьего параметра).
А: uchar ret = lib.Func(4, p, &r);
Б: uchar ret = lib.Func(4, &p, &r);