![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вызов Си-функции из dll [D6]
Piterim © (2006-09-30 01:18:00)Уважаемые мастера.
Скажите как вызвать функцию из dll, написанной на Си:
Название ее 'ex.dll'
extern "C"
{
double __declspec(dllexport) SmirnovExact (FP*,FP*);
double __declspec(dllexport) WilcoxonTest (FP*,FP*);
double __declspec(dllexport) WilcoxonSignedTest (FP*,FP*);
double __declspec(dllexport) RandomIndependent (FP*,FP*);
double __declspec(dllexport) Random (FP*,FP*);
double __declspec(dllexport) FisherIrwin (FP*,FP*);
}
BOOL WINAPI DllMain (HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
return TRUE;
}
Нужно добраться до WilcoxonTest/
Заранее спасибо.
guav (2006-10-02 14:18:00) [1]> в Си (MS VC), как мы знаем, не передаются открытые массивы,
> которые имеются в Delphi
Как элемент записи а не как отдельный параметр они и в delphi не передаются :-)
guav (2006-10-02 14:16:00) [2]
> [15] evvcom © (02.10.06 11:04)
> Хотя вряд ли, т.к. в прототипе нет ничего похожего на count
> (длина массива),
Если количества нет явно, то не значит что нельзя установить длину. Вот например для массива из char есть strlen. Видел в одной проге (на delphi кстати) формат полигона - это массив записей вершин, там для определения длины последняя дублируется.
Здесь Count, скорее всего, определяется как произведение Rows на Columns.
evvcom (2006-10-02 11:04:00) [3]> [13] guav © (02.10.06 02:11)
> Похоже, что запись будет содержать заранее неизвесное число
> элементов массива
Хотя вряд ли, т.к. в прототипе нет ничего похожего на count (длина массива), а в Си (MS VC), как мы знаем, не передаются открытые массивы, которые имеются в Delphi
evvcom (2006-10-02 10:57:00) [4]> [12] Джо © (02.10.06 02:06)
> Почему? Зачем усложнять?
[13] +
Еще и затем, что туда, вероятно, можно и nil передать. С var-ом же придется тогда хакерскими методами пользоваться (для передачи nil).
guav (2006-10-02 02:11:00) [5]> Почему? Зачем усложнять?
Похоже, что запись будет содержать заранее неизвесное число элементов массива, поэтому всё равно в вызывающей подпрограмме придётся выделять её динамически.
> TFp = packed record
Кстати, не факт что packed. #pragma pack смотреть надо и ставить соответствующий $A
Джо (2006-10-02 02:06:00) [6]> [11] guav © (02.10.06 02:04)
> и точнее тут будет не передать ссылку,
> а передать указатель.
Почему? Зачем усложнять?
guav (2006-10-02 02:04:00) [7]> (var Fp: TFp):
там два параметра. и точнее тут будет не передать ссылку, а передать указатель.
type PFt = ^TFp;
function SmirnovExact (A, B: PFp): Double; cdecl;
external 'ex.dll';
> > double Array[1]; - это вообще невесть что, массив из одного
>
> > элемента.
>
> Фактически — указатель на double. Тоже посчитал это странным.
Это массив из одного элемента, но если не проверять границы, элементов будет больше. Указатель не подойдёт, т.к. массив в той же структуре что и другие элементы.
isasa (2006-09-30 20:44:00) [8]Джо © (30.09.06 20:36) [8]
Ну, я так и знал, что напутаю :)
Ну так у меня тоже, любимое дело, перепутать индекс и длину :)
isasa (2006-09-30 20:41:00) [9]Zeqfreed © (30.09.06 20:31) [7]
Фактически — указатель на double. Тоже посчитал это странным.
Был бы, если бы
typedef struct
{
unsigned short int rows;
unsigned short int columns;
double Array[]; ===> double *Array; ===> 32bit
} FP;
а так, там все 8 байт(double) в структуре.
Джо (2006-09-30 20:36:00) [10]> [6] Desdechado © (30.09.06 20:28)
> double Array[1]; - это вообще невесть что, массив из одного
> элемента.
Ну, я так и знал, что напутаю :)
Zeqfreed (2006-09-30 20:31:00) [11]> [6] Desdechado © (30.09.06 20:28)
> double Array[1]; - это вообще невесть что, массив из одного
> элемента.
Фактически — указатель на double. Тоже посчитал это странным.
Desdechado (2006-09-30 20:28:00) [12]Джо © (30.09.06 12:27) [5]
> Если не напутал
Си тем и сбивает с толку, что в разных компиляторах типы с одинаковым названием имеют разную длину. short intобычно то же, что и int, т.е. 16 бит, т.е. здесь WORD.
double Array[1]; - это вообще невесть что, массив из одногоэлемента.
Джо (2006-09-30 12:27:00) [13]Если не напутал, прототипы на Делфи будут выглядеть как-то так:
type
TFp = packed record
Rows,
Columns: Byte;
Arr: array [0..1] of Double;
end;
function SmirnovExact (var Fp: TFp): Double; cdecl;
external 'ex.dll';
И т.п.
Piterim (2006-09-30 12:20:00) [14]typedef struct
{
unsigned short int rows;
unsigned short int columns;
double Array[1];
} FP;
Как на примере загрузить, а то через делфи сишную
функцию не разу не загружал.
isasa (2006-09-30 10:46:00) [15]palva © (30.09.06 10:24) [2]
Звездочка должна стоять перед именем, а не после.
Это не описание переменной а тип данных(ссылка на тип FP)
Кстати, а структыра FP где описана?
Как обычно LoadLibrary, GetProcAddress. Здесь cdecl.
C++ name mangling, по идее, выключен (ключевое слово extern "C")
palva (2006-09-30 10:24:00) [16]> double __declspec(dllexport) WilcoxonTest (FP*,FP*);
Это ошибка, наверное. Звездочка должна стоять перед именем, а не после.
Опишите в Delphi тип FP и передавайте параметры как var. Ну и cdecl, судя по всему, нужен.
Eraser (2006-09-30 01:58:00) [17]Вызвать с соглашением cdecl скорее всего.