Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.12;
Скачать: CL | DM;

Вниз

Вызов Си-функции из dll   Найти похожие ветки 

 
Piterim   (2006-09-30 01:18) [0]

Уважаемые мастера.
Скажите как вызвать функцию из 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/
Заранее спасибо.


 
Eraser ©   (2006-09-30 01:58) [1]

Вызвать с соглашением cdecl скорее всего.


 
palva ©   (2006-09-30 10:24) [2]

> double __declspec(dllexport) WilcoxonTest (FP*,FP*);
Это ошибка, наверное. Звездочка должна стоять перед именем, а не после.

Опишите в Delphi тип FP и передавайте параметры как var. Ну и cdecl, судя по всему, нужен.


 
isasa ©   (2006-09-30 10:46) [3]

palva ©   (30.09.06 10:24) [2]
Звездочка должна стоять перед именем, а не после.

Это не описание переменной а тип данных(ссылка на тип FP)
Кстати, а структыра FP где описана?

Как обычно LoadLibrary, GetProcAddress. Здесь cdecl.
C++ name mangling, по идее, выключен (ключевое слово extern "C")


 
Piterim   (2006-09-30 12:20) [4]

typedef struct
{
unsigned short int rows;
unsigned short int columns;
double Array[1];
} FP;

Как на примере загрузить, а то через делфи сишную
функцию не разу не загружал.


 
Джо ©   (2006-09-30 12:27) [5]

Если не напутал, прототипы на Делфи будут выглядеть как-то так:

type
 TFp = packed record
   Rows,
   Columns: Byte;
   Arr: array [0..1] of Double;
 end;

 function SmirnovExact (var Fp: TFp): Double; cdecl;
   external "ex.dll";


И т.п.


 
Desdechado ©   (2006-09-30 20:28) [6]

Джо ©   (30.09.06 12:27) [5]
> Если не напутал
Си тем и сбивает с толку, что в разных компиляторах типы с одинаковым названием имеют разную длину. short int обычно то же, что и int, т.е. 16 бит, т.е. здесь WORD.
double Array[1]; - это вообще невесть что, массив из одного элемента.


 
Zeqfreed ©   (2006-09-30 20:31) [7]

> [6] Desdechado ©   (30.09.06 20:28)


> double Array[1]; - это вообще невесть что, массив из одного
> элемента.

Фактически — указатель на double. Тоже посчитал это странным.


 
Джо ©   (2006-09-30 20:36) [8]

> [6] Desdechado ©   (30.09.06 20:28)
> double Array[1]; - это вообще невесть что, массив из одного
> элемента.

Ну, я так и знал, что напутаю :)


 
isasa ©   (2006-09-30 20:41) [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) в структуре.


 
isasa ©   (2006-09-30 20:44) [10]

Джо ©   (30.09.06 20:36) [8]
Ну, я так и знал, что напутаю :)


Ну так у меня тоже, любимое дело, перепутать индекс и длину :)


 
guav ©   (2006-10-02 02:04) [11]

> (var Fp: TFp):


там два параметра. и точнее тут будет не передать ссылку, а передать указатель.
type PFt = ^TFp;

function SmirnovExact (A, B: PFp): Double; cdecl;
  external "ex.dll";


> > double Array[1]; - это вообще невесть что, массив из одного
>
> > элемента.
>
> Фактически — указатель на double. Тоже посчитал это странным.


Это массив из одного элемента, но если не проверять границы, элементов будет больше. Указатель не подойдёт, т.к. массив в той же структуре что и другие элементы.


 
Джо ©   (2006-10-02 02:06) [12]

> [11] guav ©   (02.10.06 02:04)
> и точнее тут будет не передать ссылку,
> а передать указатель.

Почему? Зачем усложнять?


 
guav ©   (2006-10-02 02:11) [13]

> Почему? Зачем усложнять?

Похоже, что запись будет содержать заранее неизвесное число элементов массива, поэтому всё равно в вызывающей подпрограмме придётся выделять её динамически.


> TFp = packed record

Кстати, не факт что packed. #pragma pack смотреть надо и ставить соответствующий $A


 
evvcom ©   (2006-10-02 10:57) [14]

> [12] Джо ©   (02.10.06 02:06)
> Почему? Зачем усложнять?

[13] +
Еще и затем, что туда, вероятно, можно и nil передать. С var-ом же придется тогда хакерскими методами пользоваться (для передачи nil).


 
evvcom ©   (2006-10-02 11:04) [15]

> [13] guav ©   (02.10.06 02:11)
> Похоже, что запись будет содержать заранее неизвесное число
> элементов массива

Хотя вряд ли, т.к. в прототипе нет ничего похожего на count (длина массива), а в Си (MS VC), как мы знаем, не передаются открытые массивы, которые имеются в Delphi


 
guav ©   (2006-10-02 14:16) [16]


> [15] evvcom ©   (02.10.06 11:04)

> Хотя вряд ли, т.к. в прототипе нет ничего похожего на count
> (длина массива),

Если количества нет явно, то не значит что нельзя установить длину. Вот например для массива из char есть strlen. Видел в одной проге (на delphi кстати) формат полигона - это массив записей вершин, там для определения длины последняя дублируется.
Здесь Count, скорее всего, определяется как произведение Rows на Columns.


 
guav ©   (2006-10-02 14:18) [17]

> в Си (MS VC), как мы знаем, не передаются открытые массивы,
> которые имеются в Delphi

Как элемент записи а не как отдельный параметр они и в delphi не передаются :-)



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

Текущий архив: 2006.11.12;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.052 c
15-1161329175
Maximaxi
2006-10-20 11:26
2006.11.12
Скачать Delphi 4


15-1161960379
IMHO
2006-10-27 18:46
2006.11.12
Сервисы ICQ


2-1161891701
DiX
2006-10-26 23:41
2006.11.12
Помогите со временем


2-1162186962
Sergey_b
2006-10-30 08:42
2006.11.12
MDI


3-1158223456
Alex'
2006-09-14 12:44
2006.11.12
Параметры соединения DSN через BDE