![]() |
| ||
|
|
Новости |
Поиск |
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
Подскажите что не так? Подозреваю, что что-то с передачей параметров, но что точно - не знаю.
Deka (2006-04-27 16:10:00) [1]Интересно, почему игнорируется пост №3? Там уже исправлены соглашения вызовов для критической функции. Да и вообще я уже написал что ПРОБЛЕМА РЕШЕНА. Во всяком случае буду искать следующую ошибку. В документации необходимая последовательность вызовов не описана. Все что есть, это "Вызовите один раз перед началом всех операций с камерой InitControl". Про то, что надо вызвать вторую функцию для корректной работы нет ни слова. Конечно по идее надо выполнить элементарную проверку на присутствие камер при помощи вызова функции определения их числа и наверное на это рассчитывал автор DSK, НО как я понимаю, с его стороны это является ошибкой, так как нет указания на эту "фишку".
Всем спасибо.
evvcom (2006-04-27 15:20:00) [2]Скорое время = несколько команд процессора.
evvcom (2006-04-27 15:19:00) [3]
> FI: function(): Cardinal; stdcall;
это еще пройдет, так как параметров нет и стек чистить не надо.
> FC: function(var Number: Cardinal): Cardinal; stdcall;
А вот здесь словишь ошибку, так как функция в dll не будет чистить стек, потому как она так написана (cdecl), а вызывающая сторона не будет чистить, потому как будет думать, что он уже почищен. В результате в скором времени словишь исключение, скорее всего AV.
isasa (2006-04-27 15:08:00) [4]Сорри. В Opera v 8.54, напрочь, кнопки не работают :(
isasa (2006-04-27 15:06:00) [5]Я, конечно, извиняюсь, но везде звучит как,
[code]
FI: function(): Cardinal; stdcall;
FC: function(var Number: Cardinal): Cardinal; stdcall;
...
[b]@FI:= GetProcAddress(HD, 'InitControl');[/b]
...
[b]@FC:= GetProcAddress(HD, 'Connect');[/b]
[code]
Сергей М. (2006-04-27 14:02:00) [6]
> Так что НАДО сперва запросить число подключенных камер
Одно из двух - то ли невнимательное чтение док-ции производителя того самого ПО, то ли это самое ПО следует выкинуть в мусор.
evvcom (2006-04-27 13:52:00) [7]
> убрал запрос числа подключенных камер перед обращением к
> Connect - получил AV
Значит
> дай угадаю. AV по адресу 0000000C.
адрес - чистое совпадение. Видимо, вызов происходит, а дальше где-то еще есть место с потенциальным чтением с адреса 0000000C
Deka (2006-04-27 13:47:00) [8]Да. InitControl вызывается только один раз. А с призом смешно получилось. Извините и спасибо за помощь.
Только что провел простой эксперимент - убрал запрос числа подключенных камер перед обращением к Connect - получил AV. Так что НАДО сперва запросить число подключенных камер.
evvcom (2006-04-27 13:46:00) [9]
> импортирование tlib для ActiveX, который в RyeDLL.dll лежит
Что-то я там не увидел tlib. Только информация о версии. Может версии dll разные (1.3, 1.4)?
> а GetPropCameraCount - по идее, инициализирует спосок устройств
Фиг знает, чего она там инициализирует, но из себя вызывает другую функцию, адрес которой также вычисляется от глобальной переменной, которая оказалась у автора затертой после вызова InitControl. Так что...
han_malign (2006-04-27 13:31:00) [10]> Надо анализировать результат InitControl.
- кстати по всем FAQ четко прослеживается что InitControl можно вызывать только один раз...
а GetPropCameraCount - по идее, инициализирует спосок устройств, к которомы ты пытаешся пробиться с Connect...
З.Ы. Модератору - сылочку, по уму, надо бы прибить, т.к. нарушение авторских прав(погорячился), да и ссылки там битые. Правда на правильные ссылки можно выйти простеньким запросом на yandex-е(Google - пасует).
З.З.Ы. Интересно является ли нарушением авторских прав импортирование tlib для ActiveX, который в RyeDLL.dll лежит?
evvcom (2006-04-27 13:27:00) [11]Посмотри еще функцию CameraReady(int). Возможно, ее нужно вызывать для проверки готовности камеры перед InitControl.
evvcom (2006-04-27 13:15:00) [12]
> Возможно инициализация глобальной переменной прошла после
> запроса числа найденных камер.
Нет. GetPropCameraCount тоже считает адрес от той глобальной переменной. Видимо, вызов InitControl у тебя проходил неудачно и в результате затирал ту переменную. Может камера была не подключена, может еще что-то. Прав
> han_malign © (27.04.06 12:37) [12]
Надо анализировать результат InitControl. Видимо, переменная инициализируется при загрузке библиотеки, а потом в случае ошибки обниливается, и дальнейшая работа библиотеки невозможна без ее перезагрузки.
han_malign (2006-04-27 13:13:00) [13]> Если нужен приз - пиши.
http://hard1ock.narod.ru/
evvcom (2006-04-27 13:04:00) [14]Приз... :) Камеры олимпуса у меня нет. Если только бутылочку пивка! :) Но пока она дойдет из Геленджика... совсем теплая будет. :-)
Сергей М. (2006-04-27 13:04:00) [15]
> Deka © (27.04.06 12:54) [15]
А в документации к библ-ке нет ли каких-либо упоминаний об асинхронности работы тех или иных эксп.вызовов ?
Сергей М. (2006-04-27 13:02:00) [16]Извиняюсь, что-то я притормозил - обращение к FN и есть вызов ф-ции GetPropCameraCount
Сергей М. (2006-04-27 13:01:00) [17]
> Deka © (27.04.06 12:54) [15]
С какого это перепугу переменная FN в результате вызова GetProcAddress получила значение, равное числу камер ?
Число камер возвратит ф-ция GetPropCameraCount, которую ты на момент ShowMessage еще не вызывал.
Deka (2006-04-27 12:54:00) [18]Возможно инициализация глобальной переменной прошла после запроса числа найденных камер.
Вот как это выглядит:
FN:= GetProcAddress(HD, 'GetPropCameraCount');
If Assigned(FN) then begin
ShowMessage('Всего камер ' + IntToStr(FN));
end;
Ну и объявление процедуры выполнено как в [11]
Кривая какая-то библиотека!
Deka (2006-04-27 12:49:00) [19]Незнаю что я изменил, но сейчас вроде заработало. А менял я много чего. посмотрим дальше... Всем спасибо, особенно evvcom. Если нужен приз - пиши.
Deka (2006-04-27 12:42:00) [20]AV по адресу 0000000C. Правильно. Инициализация перед Connect сводится к вызову InitControl, который невозвращает ошибок. Т.е. инициализация проходит успешно. Попробовал с другой функцией из библиотеки, не требующей установки связи с камерой. Получение числа обнаруженных камер - все работает. Функция коректно вызывается, завершается и дает правильный результат.