1

Тема: C++ Seattle - допоможіть нубу підключити сторонню бібліотеку Zbar

Вітаю, Спільното!

Я в С/С++ нуб (на рівні "Хело ворлд", і протабулювати ф-ію). Та виникла потреба зробити утилітку зав'янану на БД з обробкою штрих-кодів ч/з веб-камеру. Є GNU LGPL такий собі СДК для розпізнавання штрих-кодів "Zbar". Тільки проблема в тому що під Win ставиться пакет з DLL-ками та двома консольними додатками. Один розпізнає з готового зображення, а інший має ще й інтерфейс до камери (запускається як дочірнє вікно). Навчився я запускати отой другий додаток з перехопленням вводу/виводу як по книжці:

Прихований текст
     //create pipe for the console stdout
  SECURITY_ATTRIBUTES sa;
  ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
  sa.nLength=sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle=true;
  sa.lpSecurityDescriptor=NULL;
  HANDLE ReadPipeHandle;
  HANDLE WritePipeHandle;       // not used here
  if(!CreatePipe(&ReadPipeHandle,&WritePipeHandle,&sa,0))
        RaiseLastOSError();

  //Create a Console
  STARTUPINFO si;
  ZeroMemory(&si,sizeof(STARTUPINFO));
  si.cb=sizeof(STARTUPINFO);
  si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
  si.wShowWindow=SW_HIDE;
  si.hStdOutput=WritePipeHandle;
  si.hStdError=WritePipeHandle;

  PROCESS_INFORMATION pi;
  ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
  if(!CreateProcess(NULL,L"c:\\tm\\zbarcam.exe --prescale=320x240",NULL,NULL,true,0,NULL,NULL,&si,&pi))
      RaiseLastOSError();

  //закр на запис - вседно не треба (проба)
  //CloseHandle(WritePipeHandle);

  //Read from pipe
  char Data[1024];
  for (;;)
  {
    DWORD BytesRead;
    DWORD TotalBytes;
    DWORD BytesLeft;

    //Application->ProcessMessages(); //помагає тільки не дуже

    //Check for the presence of data in the pipe
    if(!PeekNamedPipe(ReadPipeHandle,Data,sizeof(Data),&BytesRead,
        &TotalBytes,&BytesLeft))RaiseLastOSError();
    //If there is bytes, read them
    if(BytesRead)
    {
      if(!ReadFile(ReadPipeHandle,Data,sizeof(Data)-1,&BytesRead,NULL))
          RaiseLastOSError();
      Data[BytesRead]='\0';
      Memo1->Lines->Add(Data);

    }
    else
    {
      //Is the console app terminated?
      if(WaitForSingleObject(pi.hProcess,0)==WAIT_OBJECT_0)break;

    }
  }
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(ReadPipeHandle);
  CloseHandle(WritePipeHandle);

Але мінус в тому що STARTUPINFO передаю SW_HIDE (приховувати вікно), то й дочірнє (де відео), а для мого застосунку - "онука" теж приховане (((. Крім того процес який я викликаю має постійно крутитися запущеним бо ініціалізація відео-вікна відбувається досить довго і з нього я вибираю розпізнані коди, але поки мій дочірній процес висить, "висить" і моя програма. Виклик Application->ProcessMessages(); не дуже допомагає (((
Вже думав якось шукати "держак" відео-вікна через EnumChildWindows чи щось таке. Але друг Raxp, який на цих штрих-кодах давно собаку з'їв, підказав що Zbar має документацію по свому АРІ і ще порадив копати в сторону DirectShow. Але зі своїм рівнем знань я до суті доберусь років ч/з наццять ((( Для мене вже величезний прогрес що з CreateProcess трішки розібрався.
На сьогодні - ще навчився захоплювати відео зі старезною бібліотекою (але вона хоч стандартна) VFW (video for windows).
Але може з прямим використанням АРІ Zbar-сканера все спроститься?
Буду щиро вдячний за підказки та наводки!  *DRINK*

2 Востаннє редагувалося dipper (12.05.2016 15:31:50)

Re: C++ Seattle - допоможіть нубу підключити сторонню бібліотеку Zbar

Дещо надибав по підключенню бібліотек до С++ білдера.
Зробив все за порадами, і оскільки бібліотека яка мені потрібна зібрана для VC++ то зконвертував її додатком coff2omf,  підключив до ось такого зовсім простенького проекту (під спойлером):

Прихований текст
// ---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>

#pragma hdrstop

#include "tstslib.h"
#include "zbar.h"

// using namespace zbar;
// using namespace std;

// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "libzbar-0.lib"
#pragma resource "*.dfm"
TForm2 *Form2;

// ---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) {
}

// ---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender) {
    zbar::ImageScanner scanner;
    //scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
    // obtain image data
    char file[256];
    int sz=sizeof file;
    ShowMessage("розмір символьного масиву file - "+IntToStr(sz));
}
// ---------------------------------------------------------------------------

Компілиться без помилок, проте форми з кнопкою не з'являється і взагалі сумніваюся що він запускається.
Бо не проходить навіть з встановленням точки зупинки на рядку 25 і відладкою.

... тихо, сам з собою ...

Сам і відповідаю - виявляється, підключення самого лише файлу .h чи .lib не є гарантією коректного виконання.
Необхідно в папку проекту закидати також пов'язані .dll...

Але питання все ж залишається - чому на етапі компіляції чи хоча б запуску білдер не видає повідомлення про відсутні файли .dll???

3

Re: C++ Seattle - допоможіть нубу підключити сторонню бібліотеку Zbar

dipper написав:

чому на етапі компіляції чи хоча б запуску білдер не видає повідомлення про відсутні файли .dll???

З якого переляку він це має робити?

Подякували: Yola, dipper2

4

Re: C++ Seattle - допоможіть нубу підключити сторонню бібліотеку Zbar

dll - це динамічна бібліотека, помилка видасться лише коли ви спробуєте її завантажити. lib - це статична бібліотека, отже, помилка буде на етапі компіляції.

Подякували: dipper1

5

Re: C++ Seattle - допоможіть нубу підключити сторонню бібліотеку Zbar

https://ru.wikipedia.org/wiki/Portable_ … 1.82.D0.B0