Конференция "WinAPI" » работа с dll [D7, WinXP]
 
  • belmol (17.12.08 16:28) [0]
    есть вот такой пример на с++
    #pragma  once
    #include "..\\sfud\\sfuddll.h"

    #define PS_API extern "C" __declspec(dllexport)

    PS_API BOOL _stdcall PS_InitSDK();
    PS_API BOOL _stdcall PS_UnInitSDK();
    PS_API BOOL _stdcall PS_IsFtrConnected();
    PS_API int _stdcall PS_GetTimeout();
    PS_API BOOL _stdcall PS_SetTimeout(int timeout);
    PS_API BOOL _stdcall PS_IsFingerOn();
    PS_API BOOL _stdcall PS_Capture();
    PS_API void _stdcall PS_AbortCapturing();
    PS_API int _stdcall PS_GetImageWidth();
    PS_API int _stdcall PS_GetImageHeight();
    PS_API void _stdcall PS_Clear();
    PS_API void _stdcall PS_Draw(HWND hWnd, int l, int t, int r, int b, int bCore);
    PS_API int _stdcall PS_Enroll(unsigned char* Template, int* TemplateSize, int bCoreDetect);
    PS_API int _stdcall PS_GetEnrollQuality();
    PS_API BYTE* _stdcall PS_GetImageBuffer();
    PS_API int _stdcall PS_Idenify(BYTE* ImageBuf,BYTE** Templates, int Count, int* Match, int SecurityLevel, int bCoreDetect, int Timeout,int ImageWidth,int ImageHeight);
    PS_API int _stdcall PS_IdentifyTemplates(BYTE* Template1,BYTE* Template2,int SecurityLevel);
    PS_API BOOL _stdcall PS_InitSDKFtr();
    PS_API BOOL _stdcall PS_SetDiod(DIOD_STATUS status);
    PS_API BOOL _stdcall PS_SaveImage(int user_id,int fng_id);

    вот что у меня получилось

    procedure TForm36.Click(Sender: TObject);
    type
    TPS_UnInitSDK = function ():boolean;
    type
    TPS_InitSDKFtr = function ():boolean;
    type
    TPS_InitSDK = function ():boolean;
    type
    TPS_SetDiod = function (status:LongInt):boolean;
    type
    TPS_GetTimeout = function ():integer;
    type
    TPS_Capture = function ():boolean;
    type
    TPS_IsFtrConnected = function ():boolean;
    type
    TPS_Draw = procedure (hWnd:THANDLE; l,t,r,b:integer; bCore: boolean);
    type
    TPS_IsFingerOn = function ():boolean;
    var
    DLLInstance : THandle;
    PS_InitSDKFtr :TPS_InitSDKFtr;
    PS_InitSDK :TPS_InitSDK;
    PS_GetTimeout:TPS_GetTimeout;
    PS_SetDiod:TPS_SetDiod;
    PS_Capture:TPS_Capture;
    PS_IsFtrConnected:TPS_IsFtrConnected;
    PS_Draw:TPS_Draw;
    PS_UnInitSDK:TPS_UnInitSDK;
    PS_IsFingerOn:TPS_IsFingerOn;
    i: integer;
    begin
    // ïîäêëþ÷àåì áèáëèîòåêó
    DLLInstance := LoadLibrary('ProSoftSDK.dll');
    if DLLInstance = 0 then begin
      MessageDlg('Íåâîçìîæíî çàãðóçèòü DLL', mtError, [mbOK], 0);
      Exit;
    end;
    //----------------------------------- PS_InitSDK  (àêòèâèðóåì ñêàíåð)
    @PS_InitSDK := GetProcAddress(DLLInstance, '_PS_InitSDK@0');
    if @PS_InitSDK <> nil then
     begin
       PS_InitSDK;
       @PS_IsFtrConnected := GetProcAddress(DLLInstance, '_PS_IsFtrConnected@0');
       if @PS_IsFtrConnected <> nil then
         if PS_IsFtrConnected then
           for i:=0 to 5 do
           begin
             //-----------------------------------TPS_Capture
             @PS_Capture := GetProcAddress(DLLInstance, '_PS_Capture@0');
             if @PS_Capture <> nil then
               if PS_Capture then
                 begin
                   @PS_Draw := GetProcAddress(DLLInstance, '_PS_Draw@24');
                   if @PS_Draw <> nil then
                    PS_Draw(image11.Canvas.Handle,0,0,image11.Width,image11.Height,true)
                   else
                     MessageDlg('Íå íàéäåíà PS_Draw ïðîöåäóðà!.', mtError, [mbOK], 0);
                 end
             else
               begin
               MessageDlg('Íå íàéäåíà PS_Capture ïðîöåäóðà!.', mtError, [mbOK], 0);
               ShowMessage(SysErrorMessage(GetLastError));
               end;
           end
       else
         MessageDlg('Íå íàéäåíà PS_IsFtrConnected ïðîöåäóðà!.', mtError, [mbOK], 0);
     end
    else
      MessageDlg('Íå íàéäåíà PS_InitSDK ïðîöåäóðà!.', mtError, [mbOK], 0);
    //----------------------------------- PS_UnInitSDK
    @PS_UnInitSDK := GetProcAddress(DLLInstance, '_PS_UnInitSDK@0');
    if @PS_UnInitSDK <> nil then
      PS_UnInitSDK
    else
      MessageDlg('Íå íàéäåíà PS_UnInitSDK ïðîöåäóðà!.', mtError, [mbOK], 0);
    FreeLibrary(DLLInstance);
    end;

    в итоге выдает
    не найдена  PS_Capture процедура, хотя указано все верно,
    при проверке на вшивость ShowMessage(SysErrorMessage(GetLastError))
    выдает   Недостаточно памяти для обработки команды ((

    кто скажет как отловить проблемму?
  • clickmaker © (17.12.08 16:39) [1]
    > #define PS_API extern "C" __declspec(dllexport)

    это наводит на мысль, что имена функций там таки не декорированы. Т.е. не _PS_Capture@0, а PS_Capture'
  • Сергей М. © (17.12.08 16:46) [2]
    + [1]

    а также наводит на мысль, что соглашение о вызове может быть stdcall, но никак не pascal fastcall
  • belmol (18.12.08 07:26) [3]
    так самое интересное что все остальные функции импортируются и выполняются
  • wal © (18.12.08 08:49) [4]
    Ну и наконец BOOL и boolean несколько разные вещи
  • Сергей М. © (18.12.08 08:59) [5]

    > все остальные функции импортируются


    Ну так а что гадать ?

    Посмотри любым дампером/вьюером фактически экспортируемое имя проблемной функции - и все встанет на свои места.


    > и выполняются


    Не могут они выполняться правильно, потому что ты не указал stdcall.
    Если для ф-ций без параметров это еще незаметно "прокатит", то при вызове TPS_Draw ты просто обязан встетить грабли во весь рост.
  • belmol (18.12.08 14:11) [6]
    так оно и есть )
  • belmol (18.12.08 14:13) [7]
    >Не могут они выполняться правильно, потому что ты не указал stdcall.
    >Если для ф-ций без параметров это еще незаметно "прокатит", то при вызове TPS_Draw ты просто обязан встетить грабли во весь рост.

    а где указывать stdcall ??
  • clickmaker © (18.12.08 14:15) [8]
    TPS_Draw = procedure (hWnd:THANDLE; l,t,r,b:integer; bCore: boolean); stdcall;
  • belmol (18.12.08 14:46) [9]
    спасибо!
  • belmol (19.12.08 08:15) [10]
    еще вопрос
    PS_API void _stdcall PS_Draw(HWND hWnd, int l, int t, int r, int b, int bCore);
    HWND hWnd - хандл я так понял имаджа куда пихать картинку полученную в процессе сканирования..  
    int l, int t,  -- координаты окна (0,0)
    int r, int b, - высота и ширина картинки
    int bCore - отмечать крестиком или не отмечать контрольные точки на рисунке (сканирование отпечатка пальцев тут идет)

    проблеммка такая что он заливает в имадж чисто белый фон. может событие где то не так прописанно??

    begin
    // подключаем библиотеку
    i:=0;
    if dll_loaded then
    //----------------------------------- PS_InitSDK  (активируем sdk)
     if sdk_connect then
    //----------------------------------- подключен ли сканер
       if scaner_Connected then
        begin
    //----------------------------------- покажи таймаут
         showmessage('Таймаут составляет '+IntToStr(GetTimeout)+' миллисекунд '+#13+'Ширина ровна '+IntToStr(image_Width)+' пикселей '+#13+'Высота ровна '+IntToStr(image_Height)+' пикселей ');
             while (image11.Picture.Graphic = nil) do
              begin
                 diod(2);
                 if Capture then
                   if Draw_image then Imageloaded;
                 //else MessageDlg('не запущена capture', mtError, [mbOK], 0);
                 if i>20 then goto exit1;
                 i:=i+1;
              end;
           end
       else  MessageDlg('Сканер не подключен!!', mtError, [mbOK], 0);
    exit1:
    //Capture_abort;
    try
    diod(1);
    sdk_disconnect;
    dll_unloaded;
    finally end;
    end;
 
Конференция "WinAPI" » работа с dll [D7, WinXP]
Есть новые Нет новых   [134435   +34][b:0][p:0]