Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.18;
Скачать: [xml.tar.bz2];




Вниз

Как использовать Сишную dllку? Есть исходник. Нужно её вызывать из Дельфи и получать ответ. В Си я не очень. Подскажите пожалуйтса! 


Сергей Ф   (2002-02-20 04:38) [0]

Исходник на Си:


struct coor
{
int x;
int y;
};

struct CBmove
{
int ismove;
int newpiece;
int oldpiece;
struct coor from,to;
struct coor path[12];
struct coor del[12];
int delpiece[12];
} GCBmove;

int WINAPI getmove(int b[8][10],int color, double maxtime, char str[255], int *playnow, int info, int unused, struct CBmove *move);


Как надо написать вызов из Дельфи и получить результат?



Сергей Ф   (2002-02-21 08:06) [1]

Подскажите кто-нибудь, а ?



MBo   (2002-02-21 08:25) [2]

type coor=record x,y:integer end;
cbmove=record
ismove,newpiece,oldpiece:integer;
from,to:coor;
path,del:array[0..11] of coor;
delpiece:array[0..11] of integer;
end;
var gcbmove:cbmove;
function getmove(b:array[0..7,0..9] of integer;color:integer;maxtime:double;str:pchar;var playnow:integer; info,unused:integer;var move:cbmove):integer;
как вызывать- соглашение о вызове скорее всего cdecl
посмотри статью Кариха на сайте



PVOzerski   (2002-02-21 11:05) [3]

1) функция объявлена как WinAPI - соответственно, это не CDECL! Для Win16 это PASCAL,
для Win32 - STDCALL.

2) Ни в коем случае не используйте открытые массивы как параметры в этой ситуации:
их использование означает неявную передачу дополнительного параметра - длины массива -
чего Ваша DLL совсем не ждет.

3) IMHO, вот так правильнее:

type
coor=packed record
x,y:integer;
end;
CBmove=packed record
ismove,newpiece,oldpiece:integer;
from,to:coor;
path,del:array[0..11] of coor;
delpiece:array[0..11] of integer;
end;
tB=array[0..7,0..9]of integer;
tStr=array[0..254]of char;
function getmove(b:tB;color:integer;maxtime:double;
str:tStr;var playnow:integer;
info,unused:integer;var move:CBmove):integer;{$ifdef win32}stdcall;{$endif}



Сергей Ф   (2002-02-26 08:39) [4]

PVOzerski
Спасибо ! Всё работает.

MBo - тоже спасибо )


Единственное хотел спросить, а имеет значение если в Си int *playnow или int playnow ? Или получается что в Дельфи это одно и тоже вызывается как var playnow:integer; ?



Алексей Петров   (2002-02-26 09:10) [5]

int * p = var p: integer;

int p = p: integer;


Во втором случаи нет var!!!



Виктор Щербаков   (2002-02-26 09:16) [6]


> Единственное хотел спросить, а имеет значение если в Си
> int *playnow или int playnow ? Или получается что в Дельфи
> это одно и тоже вызывается как var playnow:integer; ?

playnow: integer; и var playnow: integer; - разные вещи.
В первом случае передается значение переменной playnow, во втором - адрес этой переменной, что и соответствует сишному
int *playnow. Var позволяет работать с адресом переменной как с ней самой, т.е. не применяя операции разименовывания указателя, что на мой взгляд, очень удобно.



Сергей Ф   (2002-02-27 04:51) [7]

Алексей Петров
Да точно. Не обратил внимания.


Ещё у меня обнаружился странный глюк. Не пойму откуда.
Если код такой :

ret001 := getmove( b, color, maxtime, str, playnow, info, unused, move );


StringGrid1.Cells[0, 8] := IntToStr ( ret001 );
StringGrid1.Cells[1, 8] := IntToStr ( info );
StringGrid1.Cells[1, 0] := IntToStr ( move.ismove );
StringGrid1.Cells[1, 1] := IntToStr ( move.newpiece );
StringGrid1.Cells[1, 2] := IntToStr ( move.oldpiece );
StringGrid1.Cells[1, 4] := IntToStr ( move.from.x );
StringGrid1.Cells[1, 5] := IntToStr ( move.from.y );
StringGrid1.Cells[1, 6] := IntToStr ( move.to1.x );
StringGrid1.Cells[1, 7] := IntToStr ( move.to1.y );

, то всё нормально работает.
Но стоит мне убрать строки со StringGrid, как программа начинает вылетать с ошибкой. Не понимаю в чём дело ?



dr.Flex   (2002-02-27 22:02) [8]

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

И кстати, CBmove=packed record - не факт что так правильно, обычно выравнивается на границу учетверённого слова, а packed record- это, если мне память не изменяет, на границу байта, так шо могут быть проблемы. Нужно в сишном исходнике поглядеть нету ли там таких словцов #pragma pack 1

далее тип double в разных компиляторах разного размера, это факт точно не помню где есть как но бывает и 10 байт

всякие array использовать в описании параметров это черевато изысканными граблями, лучше объявть поинтер распределить память потом закастить к массиву, тогда будет всё понятно, можно менее понятно - передать @barray. Далее тоже самое нужно сделать и со структурой, var параметры это ненадёжно, просто структуру нужно сделать ^cbmvoe динамической распределить память и передать поинтер.

последне, лучше не передавать ссылки на переменные распределённые в стеке, а именно это тыи делаешь с масивами, структурой и строкой.

Итого вызов на мой взгляд скорее всего должен выглядеть так:

int WINAPI getmove(int b[8][10],int color, double maxtime, char str[255], int *playnow, int info, int unused, struct CBmove *move);

type
TcbBuff = array[8][10] of integer;
PcbBuff = ^TcbBuff;
pInteger = ^integer;
PCBMove = ^CBMove;

function getmvoe(b:pointer; color:integer
maxtime:double{возможно Extended};
str:PChar; playnow:pInteger;
info:integer; unused:integer;
move: PCBMove):integer;stdcall;

//
var
MyMove :PCBMove;
Buff :PcbBuff;
maxtime:double;
str :PChar;
playnow,
info, res
unused,
color :integer;
begin
MyMove:=New(PCBMove);
MyMove^.ismove:=100;//тильду можно не писать, но лучше писать
...
Buff:=New(PcbBuff);
Buff^[0,0]:=100;//тильду можно не писать, но лучше писать
...
Str:=StrAlloc(256);
...
...
...
res:=getmvoe(Buff, color, maxtime, @playnow, info, unused, MyMove);
end;

успехов в трубе :-))



Сергей Ф   (2002-03-02 06:49) [9]

dr.Flex
Покопался в этой проблеме и обнаружил что дело видимо в playnow.

Если перед вызовом функции написать
playnow :=0;
то всё работает без глюков. StringGridы можно убирать.

Правда если написать скажем
playnow :=1;
, то проблема остаётся.

Причём playnow я описывал обоими способоми. Результат одинаковый.
Во втором способе Delphi ругается на @ в @playnow. Поэтому я его прописал как playnow:pointer;

Есть ли ещё какие вариатны как можно прописать этот чёртов указатель ? Может память надо отвести каким то особым образом ? Или ещё что-то ?




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.18;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.024 c
7-57544           Soul                  2001-12-06 15:35  2002.03.18  
GDI


3-57333           Андре                 2002-02-20 08:58  2002.03.18  
Поиск по базе


3-57321           AndrewK               2002-02-19 17:48  2002.03.18  
Как составить запрос


3-57320           xtremer               2002-02-19 14:51  2002.03.18  
О BDE и больших базах данных


3-57312           draculenok            2002-02-18 13:29  2002.03.18  
Помогите программеры!!!!!!!