![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Импорт функций из сишной DLL... Вроде все просто, а не работает. [WinXP]
Deka © (2006-04-26 16:39:00)
procedure TTestForm.Button1Click(Sender: TObject);
var
HD: HModule;
FI: function(): Cardinal; stdcall;
FC: function(var Number: Cardinal): Cardinal; stdcall;
NN: Cardinal;
begin
HD:= LoadLibrary('RyeDLL.dll');
try
If HD <> 0 then begin
FI:= GetProcAddress(HD, 'InitControl');
If Assigned(FI) then begin
FI; // Это работает
FC:= GetProcAddress(HD, 'Connect');
If Assigned(FC) then begin
NN:= 0;
FC(NN); // А это не работает
end;
end;
end;
finally
FreeLibrary(HD);
end;
end;
Из файла RyeDll.h
RYEDLL_API LONG32 InitControl();
RYEDLL_API LONG32 Connect(LONG32 nCamNum);
Ошибка (акцесс виолэйшн) возникает в строкеFC(NN);в модуле ntdll.dll
Подскажите что не так? Подозреваю, что что-то с передачей параметров, но что точно - не знаю.
han_malign (2006-04-27 12:37:00) [21]> AV по адресу 0000000C. Правильно? Значит эта самая глобальная переменная не инициализирована.
- а я бы еще посмотрел что возвращает - InitControl.
Наверняка ведь ошибку...
evvcom (2006-04-27 12:28:00) [22]IDA определил ее как
int __cdecl Connect(int);
т.е. соглашение однозначно поставить cdecl. Определить характер параметра не удалось, т.к. из Connect вызывается другая функция, адрес которой берется из глобальной переменнойи рассчитывается где-то раньше. Но судя по "LONG32 nCamNum" можно поставить Integer по значению. Что возвращает, тоже определяется в вызываемой функции.
В дельфи:
type
TFunConnect = function(Number: Longint): Longint; cdecl;
Если не работает, то дай угадаю. AV по адресу 0000000C. Правильно? Значит эта самая глобальная переменнаяне инициализирована. Смотри документацию, как ты должен перед коннектом инициализировать. Хотя, если говоришь, что InitControl работает... Она тоже из той же глобальной переменной данные берет.
Попробуй посмотреть отладчиком в CPU Window.
Deka (2006-04-27 11:38:00) [23]Ок. Спасибо. Отправил. Имя функции Connect. Надеюсь с остальными проблем не будет (с остальными функциями). Просто Connect ключевая - подключение к фотоаппарату.
evvcom (2006-04-27 11:23:00) [24]Даже перебрав все комбинации, нельзя быть уверенным, что все ок. Надо наверняка. Ну шли эту dll мне на мыло, ИДА-шкой посмотрю, что там. Имя функции Connect? Надеюсь, она небольшая?
Deka (2006-04-27 09:16:00) [25]Как я только не ставил... и var... и const... и вообще без ничего - не работает. Любому человеку который сможет экспортировать функции из RyeDLL.dll подарю SDK для управления фотоаппаратами Olympus. Собственно из этого SDK и библиотека. Есть пример использования этой библиотеки на C. полное описание и все необходимое для сборки проектов с использованием этой библиотеки в сишных проектах.
P.S. Соглашения о вызовах тоже все перепробовал...
MBo (2006-04-26 18:15:00) [26]>Cashmare
сишные функции, экспортируемые из DLL, могут быть с разными соглашениями о вызове - конкретное соглашение для каждой функции описано в заголовочном файле.
А просто от фонаря ставить соглашение - мягко говоря, не выход...
Cashmare (2006-04-26 18:10:00) [27]MBo © (26.04.06 17:57) [5]
stdcall должно быть, а не cdecl
Я долго писал stdcall на сишные функции, пока не столкнулся с количеством вызова сишной функции по многу миллионов раз (в отдельном потоке) за время выполнения программы. Через некоторое время работы прога падала из-за переполнения стека. После замены stdcall на cdecl все стало нормально работать. Наверно, я чего-то не понимаю...
MBo (2006-04-26 17:57:00) [28]stdcall должно быть, а не cdecl
Connect(LONG32 nCamNum) - передача параметра по значению, а не по ссылке, так что var убери
FC: function(Number: Integer): Integer; stdcall;
Deka (2006-04-26 17:50:00) [29][3] Это вот это?
#define RYEDLL_API __declspec(dllexport)
Deka (2006-04-26 17:49:00) [30][1] Сделал так:
procedure TTestForm.Button5Click(Sender: TObject);
var
HD: HModule;
FI: function(): LongInt; stdcall;
FC: function(var Number: LongInt): LongInt; cdecl;
NN: LongInt;
begin
HD:= LoadLibrary('RyeDLL.dll');
try
If HD <> 0 then begin
FI:= GetProcAddress(HD, 'InitControl');
If Assigned(FI) then begin
FI;
FC:= GetProcAddress(HD, 'Connect');
If Assigned(FC) then begin
NN:= 0;
FC(NN);
end;
end;
end;
finally
FreeLibrary(HD);
end;
end;
- Таже ошибка.
[2] - Что есть определение?
P.S. Ну не шарю я в Си!
MBo (2006-04-26 17:20:00) [31]RYEDLL_API - посмотри определение
SuperBUG (2006-04-26 17:02:00) [32]не совсем в тему,но LONG32-32-bit signed integer
Cardinal-unsigned 32 bit
судя по тому что происходит вызов и в первом случае ошибки нет а во втором в наличии есть cмысл поиграться с calling convetion,например попробовать вместо stdcall cdecl