Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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;

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



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

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

Наверх





Память: 0.48 MB
Время: 0.005 c
1-57398
Alex
2002-03-01 20:21
2002.03.18
Dll


4-57571
MrAngel
2002-01-21 12:11
2002.03.18
И ещё один вопрос!!! Само описание HWND и HDC. Их внутренняя структура.


1-57365
Анонимщик
2002-03-01 14:07
2002.03.18
Как сделать хинт, которыйбы перемещался вместе с мышиным курсором и был под ним?


1-57384
Тот самый Пацан
2002-02-28 23:57
2002.03.18
Как вывести на обратный план Memo, a на передний - Image...


4-57560
andersen
2002-01-15 21:40
2002.03.18
Как узнать в Интернете я или нет?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский