Текущий архив: 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.48 MB
Время: 0.048 c