3rd party c wrapper functions for harbour

User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

3rd party c wrapper functions for harbour

Post by reinaldocrespo »

Hello forum;

I'm trying to use a 3rd party library .dll to OCR tif images. I chose Transym http://www.transym.com . In order to access their functions I've written .c wrappers. Currently my sample app GPFs. Can someone help with harbour's vm .c interface?

Here is my self-contained reduced sample code:

Code: Select all

//request hb_gt_win   //needed for console mode app.

#define TOCRJOBTYPE_TIFFFILE 0      // TOCRJOBINFO.InputFile specifies a tiff file

FUNCTION MAIN() 
LOCAL TestTifFile := "sample.tif"

   //SetMode(25,80)      //25 lines by 80 columns console
   IF !FILE( TestTifFile ) 
      Alert( "testfile sample.tif not found" ) 
      return NIL 
   ENDIF 

   OCRFromFileUsingTransym( TestTifFile, TOCRJOBTYPE_TIFFFILE ) 
   
RETURN NIL 

//-----------------------------------------------------------
#pragma BEGINDUMP

// Transym constants below 
#define TOCR_OK 0
#define TOCRJOBTYPE_TIFFFILE 0      // TOCRJOBINFO.InputFile specifies a tiff file
#define TOCRJOBTYPE_DIBFILE 1       // TOCRJOBINFO.InputFile specifies a dib (bmp) file
#define TOCRJOBTYPE_DIBCLIPBOARD 2  // clipboard contains a dib (clipboard format CF_DIB)
#define TOCRJOBTYPE_MMFILEHANDLE  3 // TOCRJOBINFO.PageNo specifies a handle to a memory mapped DIB file

#define TOCRCONFIG_DEFAULTJOB -1    // default job number (all new jobs)
#define TOCRCONFIG_DLL_ERRORMODE 0  // set the dll ErrorMode
#define TOCRCONFIG_SRV_ERRORMODE 1  // set the service ErrorMode
#define TOCRCONFIG_SRV_THREADPRIORITY 2 // set the service thread priority
#define TOCRCONFIG_DLL_MUTEXWAIT 3  // set the dll mutex wait timeout (ms)
#define TOCRCONFIG_DLL_EVENTWAIT 4  // set the dll event wait timeout (ms)
#define TOCRCONFIG_SRV_MUTEXWAIT 5  // set the service mutex wait timeout (ms)
#define TOCRCONFIG_LOGFILE 6        // set the log file name

// Setting for JobNo for TOCRSetErrorMode and TOCRGetErrorMode
#define TOCRDEFERRORMODE -1         // set/get the default API error mode (applies
                                    // when there are no jobs and is applied to new jobs)

// Settings for ErrorMode for TOCRSetErrorMode and TOCRGetErrorMode
#define TOCRERRORMODE_NONE 0        // errors unseen (use return status of API calls)
#define TOCRERRORMODE_MSGBOX 1      // errors will bring up a message box
#define TOCRERRORMODE_LOG 2         // errors are sent to a log file

// Values returned by TOCRGetJobStatus JobStatus
#define TOCRJOBSTATUS_ERROR -1      // an error ocurred
#define TOCRJOBSTATUS_BUSY 0        // the job is still processing
#define TOCRJOBSTATUS_DONE 1        // the job completed successfully
#define TOCRJOBSTATUS_IDLE 2        // no job has been specified yet

// Settings for Mode for TOCRGetJobResultsEx
#define TOCRGETRESULTS_NORMAL 0     // return results for TOCRRESULTS
#define TOCRGETRESULTS_EXTENDED 1   // return results for TOCRRESULTSEX


typedef struct tagTOCRProcessOptions
{
    long        StructId;
    short       InvertWholePage;
    short       DeskewOff;
    char     Orientation;
    short       NoiseRemoveOff;
    short       LineRemoveOff;
    short       DeshadeOff;
    short       InvertOff;
    short       SectioningOn;
    short       MergeBreakOff;
    short       LineRejectOff;
    short       CharacterRejectOff;
    short       LexOff;
    short       DisableCharacter[256];
} TOCRPROCESSOPTIONS;


typedef struct tagTOCRJobInfo2
{
    long        StructId;
    long        JobType;
    char        *InputFile;
    //HANDLE    hMMF;
    long     hMMF;
    long        PageNo;
    TOCRPROCESSOPTIONS  ProcessOptions;
} TOCRJOBINFO2;


typedef struct tagTOCRJobInfo
{
    long        StructId;
    long        JobType;
    char        *InputFile;
    long        PageNo;
    TOCRPROCESSOPTIONS  ProcessOptions;
} TOCRJOBINFO;


typedef struct tagTOCRRESULTSHEADER
{
    long        StructId;
    long        XPixelsPerInch;
    long        YPixelsPerInch;
    long        NumItems;
    float       MeanConfidence;
} TOCRRESULTSHEADER;

typedef struct tagTOCRRESULTSITEM
{
    unsigned short  StructId;
    unsigned short  OCRCha;
    float           Confidence;
    unsigned short  XPos;
    unsigned short  YPos;
    unsigned short  XDim;
    unsigned short  YDim;
} TOCRRESULTSITEM;


typedef struct tagTOCRRESULTS
{
    TOCRRESULTSHEADER   Hdr;
    TOCRRESULTSITEM     Item[1];
} TOCRRESULTS;


typedef struct tagTOCRRESULTSITEMEXALT
{
    unsigned short  Valid;
    unsigned short  OCRCha;
    float           Factor;
} TOCRRESULTSITEMEXALT;


typedef struct tagTOCRRESULTSITEMEX
{
    unsigned short          StructId;
    unsigned short          OCRCha;
    float                   Confidence;
    unsigned short          XPos;
    unsigned short          YPos;
    unsigned short          XDim;
    unsigned short          YDim;
    TOCRRESULTSITEMEXALT    Alt[5];
} TOCRRESULTSITEMEX;


typedef struct tagTOCRRESULTSEX
{
    TOCRRESULTSHEADER   Hdr;
    TOCRRESULTSITEMEX   Item[1];
} TOCRRESULTSEX;


//--------------------------------------------------------
//parameters 
// 1. input file with image 
// 2. type of file to ocr //should default to TIFF 
//returns OCRed text 
HB_FUNC( OCRFROMFILEUSINGTRANSYM )
{
   TOCRJOBINFO2 JobInfo2;
    TOCRRESULTS     *Results = 0;
    long                Status;
    long                JobNo;
    char                Msg[8192];
   const char * InputFile = hb_parcx( 1 );   //parm 1 is input file

   //Sets Transym to show error on a windows dialog box 
    TOCRSetConfig( TOCRCONFIG_DEFAULTJOB, TOCRCONFIG_DLL_ERRORMODE, TOCRERRORMODE_MSGBOX );

    memset( &JobInfo2, 0, sizeof( TOCRJOBINFO2 ) );

    JobInfo2.JobType = hb_parni( 2 ) ; //TOCRJOBTYPE_TIFFFILE;
    JobInfo2.InputFile = InputFile;
    Status = TOCRInitialise( &JobNo );

    if ( Status == TOCR_OK ) {
        if ( OCRWait( JobNo, JobInfo2 ) ) {
            if ( GetResults( JobNo, &Results ) ) {

                FormatResults( Results, Msg );
            hb_xfree( Results );    //free( Results );
            }
        }

        TOCRShutdown( JobNo );
    } /**/
    hb_retc( Msg ) ;
}

//--------------------------------------------------------
BOOL OCRWait( long JobNo, TOCRJOBINFO2 JobInfo2 )
{
    long                Status;
    long                JobStatus;
    long                ErrorMode;
    char                Msg[4096];

    Status = TOCRDoJob2( JobNo, &JobInfo2 );
    if (Status == TOCR_OK) {
        Status = TOCRWaitForJob(JobNo, &JobStatus);
    }
    
    if (Status == TOCR_OK && JobStatus == TOCRJOBSTATUS_DONE)
    {
        return TRUE;
    } else {
        // If something hass gone wrong display a message
        // (Check that the OCR engine hasn't already displayed a message)
        TOCRGetConfig(JobNo, TOCRCONFIG_DLL_ERRORMODE, &ErrorMode);
        if ( ErrorMode == TOCRERRORMODE_NONE ) {
            TOCRGetJobStatusMsg(JobNo, Msg);
            //MessageBox( NULL, Msg, "OCRWait", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP );
        }
        return FALSE;
    }
} // OCRWait()


//--------------------------------------------------------
// Get the results from TOCR
BOOL getresults(long JobNo, long mode, void **Results)
{
    long                Status;
    long                ResultsInf;
    char                Msg[4096];


    Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, 0);
    if ( Status != TOCR_OK ) {
        //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
        //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE;

    }
    if ( ResultsInf > 0 ) {
        // Allocate memory for results
      *Results = ( char * ) hb_xgrab( ResultsInf + 1 );
       //memset( &Results, 0, sizeof( ResultsInf ) );

      // Retrieve the results
        Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, *Results);
        if ( Status != TOCR_OK ) {
           //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
            //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
         hb_xfree( Results );    //free(*Results);
            *Results = 0;
            return FALSE;
        }
    } else {
        //MessageBox(NULL, "No results found\n", "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE ;
    }
    
    return TRUE;
} // getresults()


//--------------------------------------------------------
// Get extended results
BOOL GetResults( long JobNo, TOCRRESULTSEX **Results )
{
    return getresults( JobNo, TOCRGETRESULTS_EXTENDED, (void **)Results );
} // GetResults()


//--------------------------------------------------------
// Convert extended results to a string
BOOL FormatResults(TOCRRESULTSEX *Results, char *Msg)
{
    long            ItemNo;
    long            APos = 0;
    BOOL            Status = FALSE;

    if ( Results->Hdr.NumItems > 0 ) {
        for (ItemNo = 0; ItemNo < Results->Hdr.NumItems; ItemNo ++ ) {
            if ( Results->Item[ItemNo].OCRCha == '\r' )
                Msg[APos] = '\n';
            else
                Msg[APos] = (char)Results->Item[ItemNo].OCRCha;
            APos ++;
        }
        Msg[APos] = 0;
        Status = TRUE;
    }

    return Status;
} // FormatResults()


#pragma ENDDUMP

 
If someone here has experience with harbour's vm I will send you the API's documentation and .dll you will need to test. Please write to reinaldo dot crespo at gmail.

Thank you,


Reinaldo.
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

Reinaldo,

The used DLL functions must be prototyped, in example:

// Function TOCRInitialise (ByRef JobNo As Integer) As Integer

int TOCRInitialise( int * JobNo );

Usually the DLL developers should provide a header file with the C language prototypes.
If not, then you can build it yourself.

We need to include those prototypes in your code so the C compiler can properly use them.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

The easiest way to trace it is to place several calls to:

MessageBox( 0, "here", "ok 1", 0 );

so you can find which function GPFs
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

You must include:

#include <windows.h>

in order to use MessageBox()
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: 3rd party c wrapper functions for harbour

Post by cnavarro »

Reinaldo,
Have you tried the example they let you download?
In this example all the header files with the definitions of the functions
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: 3rd party c wrapper functions for harbour

Post by reinaldocrespo »

Everyone;

I did not include prototype definitions as it really doesn't make any difference. After all, you only get warnings back from the compiler. By not including these external headers I was hoping it would be easier for others to compile and give it a hack. To make things clearer, I've now added .h inclusions. You may download the .dll, .lib, my sample.tif as well as all the .h header files from a public directory I have at http://lac.structuredsystems.com/temp/: I understand this is all you will need to build and test. Again, I believe the problem is with my wrapper functions or the structure declarations. The GPF happens when executing TOCRDoJob2().

Here is my new source:

Code: Select all

request hb_gt_win   //needed for console mode app.

#define TOCRJOBTYPE_TIFFFILE 0      // TOCRJOBINFO.InputFile specifies a tiff file

FUNCTION MAIN() 
LOCAL TestTifFile := "sample.tif"

   SetMode(25,80)      //25 lines by 80 columns console
   IF !FILE( TestTifFile ) 
      Alert( "testfile sample.tif not found" ) 
      return NIL 
   ENDIF 

   OCRFromFileUsingTransym( TestTifFile, TOCRJOBTYPE_TIFFFILE ) 
   
RETURN NIL 

//-----------------------------------------------------------
#pragma BEGINDUMP
#include <hbapi.h>
#include <windows.h>
//#include <tocrdll.h>
#include <tocruser.h>
#include <tocrerrs.h>


typedef struct _TOCRProcessOptions
{
    long        StructId;
    short       InvertWholePage;
    short       DeskewOff;
    char     Orientation;
    short       NoiseRemoveOff;
    short       LineRemoveOff;
    short       DeshadeOff;
    short       InvertOff;
    short       SectioningOn;
    short       MergeBreakOff;
    short       LineRejectOff;
    short       CharacterRejectOff;
    short       LexOff;
    short       DisableCharacter[256];
} TOCRPROCESSOPTIONS;


typedef struct _TOCRJobInfo2
{
    long        StructId;
    long        JobType;
    char        *InputFile;
    //HANDLE    hMMF;
    long     hMMF;
    long        PageNo;
    TOCRPROCESSOPTIONS  ProcessOptions;
} TOCRJOBINFO2;


typedef struct _TOCRJobInfo
{
    long        StructId;
    long        JobType;
    char        *InputFile;
    long        PageNo;
    TOCRPROCESSOPTIONS  ProcessOptions;
} TOCRJOBINFO;


typedef struct _TOCRRESULTSHEADER
{
    long        StructId;
    long        XPixelsPerInch;
    long        YPixelsPerInch;
    long        NumItems;
    float       MeanConfidence;
} TOCRRESULTSHEADER;

typedef struct _TOCRRESULTSITEM
{
    unsigned short  StructId;
    unsigned short  OCRCha;
    float           Confidence;
    unsigned short  XPos;
    unsigned short  YPos;
    unsigned short  XDim;
    unsigned short  YDim;
} TOCRRESULTSITEM;


typedef struct _TOCRRESULTS
{
    TOCRRESULTSHEADER   Hdr;
    TOCRRESULTSITEM     Item[1];
} TOCRRESULTS;


typedef struct _TOCRRESULTSITEMEXALT
{
    unsigned short  Valid;
    unsigned short  OCRCha;
    float           Factor;
} TOCRRESULTSITEMEXALT;


typedef struct _TOCRRESULTSITEMEX
{
    unsigned short          StructId;
    unsigned short          OCRCha;
    float                   Confidence;
    unsigned short          XPos;
    unsigned short          YPos;
    unsigned short          XDim;
    unsigned short          YDim;
    TOCRRESULTSITEMEXALT    Alt[5];
} TOCRRESULTSITEMEX;


typedef struct _TOCRRESULTSEX
{
    TOCRRESULTSHEADER   Hdr;
    TOCRRESULTSITEMEX   Item[1];
} TOCRRESULTSEX;

extern long TOCRInitialise(long *JobNo);
extern long TOCRShutdown(long JobNo);
extern long TOCRDoJob2(long JobNo, TOCRJOBINFO2 *JobInfo2);
extern long TOCRWaitForJob(long JobNo, long *JobStatus);
extern long TOCRWaitForAnyJob(long *WaitAnyStatus, long *JobNo);
extern long TOCRGetJobDBInfo(long *JobSlotInf);
extern long TOCRGetJobStatus(long JobNo, long *JobStatus);
extern long TOCRGetJobStatusEx(long JobNo, long *JobStatus, float *Progress, long *AutoOrientation);
extern long TOCRGetJobStatusMsg(long JobNo, char *Msg);
extern long TOCRGetNumPages(long JobNo, char *Filename, long JobType, long *NumPages);
extern long TOCRGetJobResults(long JobNo, long *ResultsInf, TOCRRESULTS *Results);
extern long TOCRGetJobResultsEx(long JobNo, long Mode, long *ResultsInf, void *ResultsEx);
extern long TOCRGetLicenceInfoEx(long JobNo, char *Licence, long *Volume, long *Time, long *Remaining, long *Features);
extern long TOCRConvertFormat(long JobNo, void *InputAddr, long InputFormat, void *OutputAddr, long OutputFormat, long PageNo);
extern long TOCRSetConfig(long JobNo, long Parameter, long Value);
extern long TOCRGetConfig(long JobNo, long Parameter, long *Value);

BOOL OCRWait(long JobNo, TOCRJOBINFO2 JobInfo2);
BOOL GetResults(long JobNo, TOCRRESULTSEX **Results);
BOOL FormatResults(TOCRRESULTSEX *Results, char *Msg);

/**/
//--------------------------------------------------------
//parameters 
// 1. input file with image 
// 2. type of file to ocr //should default to TIFF 
//returns OCRed text 
HB_FUNC( OCRFROMFILEUSINGTRANSYM )
{
   TOCRJOBINFO2 JobInfo2;
    TOCRRESULTS     *Results = 0;
    long                Status;
    long                JobNo;
    char                Msg[8192];
   const char * InputFile = hb_parcx( 1 );   //parm 1 is input file

   //Sets Transym to print error to log file tocr.log
    TOCRSetConfig( TOCRCONFIG_DEFAULTJOB, TOCRCONFIG_DLL_ERRORMODE, TOCRERRORMODE_MSGBOX );

    memset( &JobInfo2, 0, sizeof( TOCRJOBINFO2 ) );

    JobInfo2.JobType = hb_parni( 2 ) ; //TOCRJOBTYPE_TIFFFILE;
    JobInfo2.InputFile = InputFile;
    Status = TOCRInitialise( &JobNo );

    if ( Status == TOCR_OK ) {
        if ( OCRWait( JobNo, JobInfo2 ) ) {
            if ( GetResults( JobNo, &Results ) ) {

                FormatResults( Results, Msg );
            hb_xfree( Results );    //free( Results );
            }
        }

        TOCRShutdown( JobNo );
    } /**/
    hb_retc( Msg ) ;
}

//--------------------------------------------------------
BOOL OCRWait( long JobNo, TOCRJOBINFO2 JobInfo2 )
{
    long                Status;
    long                JobStatus;
    long                ErrorMode;
    char                Msg[4096];

    Status = TOCRDoJob2( JobNo, &JobInfo2 );
    if (Status == TOCR_OK) {
        Status = TOCRWaitForJob(JobNo, &JobStatus);
    }
    
    if (Status == TOCR_OK && JobStatus == TOCRJOBSTATUS_DONE)
    {
        return TRUE;
    } else {
        // If something hass gone wrong display a message
        // (Check that the OCR engine hasn't already displayed a message)
        TOCRGetConfig(JobNo, TOCRCONFIG_DLL_ERRORMODE, &ErrorMode);
        if ( ErrorMode == TOCRERRORMODE_NONE ) {
            TOCRGetJobStatusMsg(JobNo, Msg);
            //MessageBox( NULL, Msg, "OCRWait", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP );
        }
        return FALSE;
    }
} // OCRWait()


//--------------------------------------------------------
// Get the results from TOCR
BOOL getresults(long JobNo, long mode, void **Results)
{
    long                Status;
    long                ResultsInf;
    char                Msg[4096];


    Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, 0);
    if ( Status != TOCR_OK ) {
        //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
        //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE;

    }
    if ( ResultsInf > 0 ) {
        // Allocate memory for results
      *Results = ( char * ) hb_xgrab( ResultsInf + 1 );
       //memset( &Results, 0, sizeof( ResultsInf ) );

      // Retrieve the results
        Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, *Results);
        if ( Status != TOCR_OK ) {
           //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
            //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
         hb_xfree( Results );    //free(*Results);
            *Results = 0;
            return FALSE;
        }
    } else {
        //MessageBox(NULL, "No results found\n", "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE ;
    }
    
    return TRUE;
} // getresults()


//--------------------------------------------------------
// Get extended results
BOOL GetResults( long JobNo, TOCRRESULTSEX **Results )
{
    return getresults( JobNo, TOCRGETRESULTS_EXTENDED, (void **)Results );
} // GetResults()


//--------------------------------------------------------
// Convert extended results to a string
BOOL FormatResults(TOCRRESULTSEX *Results, char *Msg)
{
    long            ItemNo;
    long            APos = 0;
    BOOL            Status = FALSE;

    if ( Results->Hdr.NumItems > 0 ) {
        for (ItemNo = 0; ItemNo < Results->Hdr.NumItems; ItemNo ++ ) {
            if ( Results->Item[ItemNo].OCRCha == '\r' )
                Msg[APos] = '\n';
            else
                Msg[APos] = (char)Results->Item[ItemNo].OCRCha;
            APos ++;
        }
        Msg[APos] = 0;
        Status = TRUE;
    }

    return Status;
} // FormatResults()


#pragma ENDDUMP
 
Notice I'm not including their tocdll.h declarations. This is because their external functions declaration follows a more strict vc format and we need to declare them in a harbour vm more friendly manner.

I hope I can recruit someone with harbour vm experience to help make Transym OCR work with Harbour.

Thank you,


Reinaldo.
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Enrico Maria Giordano »

reinaldocrespo wrote:I did not include prototype definitions as it really doesn't make any difference. After all, you only get warnings back from the compiler.
This is not true. In C language, if a function declaration is missing, the compiler assumes all int types for the parameter and the return value, that is most probably wrong and results in a GPF.

EMG
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: 3rd party c wrapper functions for harbour

Post by reinaldocrespo »

Well, thank you. I did not know the compiler assumed int. However, with my revised code that includes prototype declarations, I still have the same problem. Code with prototypes is shared on my previous entry on this thread. I have placed all the files needed to recreate the project on a temporary server directory: http://lac.structuredsystems.com/temp/

Perhaps someone can help?


Reinaldo.
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

This modified version is compiling clean:

transym.prg

Code: Select all

request hb_gt_win   //needed for console mode app.

#define TOCRJOBTYPE_TIFFFILE 0      // TOCRJOBINFO.InputFile specifies a tiff file

FUNCTION MAIN() 
LOCAL TestTifFile := "sample.tif"

   SetMode(25,80)      //25 lines by 80 columns console
   IF !FILE( TestTifFile ) 
      Alert( "testfile sample.tif not found" ) 
      return NIL 
   ENDIF 

   OCRFromFileUsingTransym( TestTifFile, TOCRJOBTYPE_TIFFFILE ) 
   
RETURN NIL 

//-----------------------------------------------------------

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>
#include "TOCRdll.h"
#include "TOCRuser.h"
#include "TOCRerrs.h"

BOOL OCRWait( long JobNo, TOCRJOBINFO2 JobInfo2 );
BOOL GetResults( long JobNo, TOCRRESULTSEX ** Results );
BOOL FormatResults( TOCRRESULTSEX * Results, char * Msg );

//--------------------------------------------------------
//parameters 
// 1. input file with image 
// 2. type of file to ocr //should default to TIFF 
//returns OCRed text 

HB_FUNC( OCRFROMFILEUSINGTRANSYM )
{
    TOCRJOBINFO2 JobInfo2;
    TOCRRESULTSEX  * Results = 0;
    long                Status;
    long                JobNo;
    char                Msg[8192];
    char * InputFile = ( char * ) hb_parcx( 1 );   //parm 1 is input file

   //Sets Transym to print error to log file tocr.log
    TOCRSetConfig( TOCRCONFIG_DEFAULTJOB, TOCRCONFIG_DLL_ERRORMODE, TOCRERRORMODE_MSGBOX );

    memset( &JobInfo2, 0, sizeof( TOCRJOBINFO2 ) );

    JobInfo2.JobType = hb_parni( 2 ) ; //TOCRJOBTYPE_TIFFFILE;
    JobInfo2.InputFile = InputFile;
    Status = TOCRInitialise( &JobNo );

    if ( Status == TOCR_OK ) {
        if ( OCRWait( JobNo, JobInfo2 ) ) {
            if ( GetResults( JobNo, &Results ) ) {

                FormatResults( Results, Msg );
            hb_xfree( Results );    //free( Results );
            }
        }

        TOCRShutdown( JobNo );
    } /**/
    hb_retc( Msg ) ;
}

//--------------------------------------------------------
BOOL OCRWait( long JobNo, TOCRJOBINFO2 JobInfo2 )
{
    long                Status;
    long                JobStatus;
    long                ErrorMode;
    char                Msg[4096];

    Status = TOCRDoJob2( JobNo, &JobInfo2 );
    if (Status == TOCR_OK) {
        Status = TOCRWaitForJob(JobNo, &JobStatus);
    }
    
    if (Status == TOCR_OK && JobStatus == TOCRJOBSTATUS_DONE)
    {
        return TRUE;
    } else {
        // If something hass gone wrong display a message
        // (Check that the OCR engine hasn't already displayed a message)
        TOCRGetConfig(JobNo, TOCRCONFIG_DLL_ERRORMODE, &ErrorMode);
        if ( ErrorMode == TOCRERRORMODE_NONE ) {
            TOCRGetJobStatusMsg(JobNo, Msg);
            //MessageBox( NULL, Msg, "OCRWait", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP );
        }
        return FALSE;
    }
} // OCRWait()


//--------------------------------------------------------
// Get the results from TOCR
BOOL getresults(long JobNo, long mode, void **Results)
{
    long                Status;
    long                ResultsInf;
    char                Msg[4096];


    Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, 0);
    if ( Status != TOCR_OK ) {
        //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
        //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE;

    }
    if ( ResultsInf > 0 ) {
        // Allocate memory for results
      *Results = ( char * ) hb_xgrab( ResultsInf + 1 );
       //memset( &Results, 0, sizeof( ResultsInf ) );

      // Retrieve the results
        Status = TOCRGetJobResultsEx(JobNo, mode, &ResultsInf, *Results);
        if ( Status != TOCR_OK ) {
           //sprintf(Msg, "TOCRGetJobResultsEx failed - %d\n", Status);
            //MessageBox(NULL, Msg, "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
         hb_xfree( Results );    //free(*Results);
            *Results = 0;
            return FALSE;
        }
    } else {
        //MessageBox(NULL, "No results found\n", "getresults", MB_TASKMODAL | MB_TOPMOST | MB_ICONSTOP);
        return FALSE ;
    }
    
    return TRUE;
} // getresults()


//--------------------------------------------------------
// Get extended results
BOOL GetResults( long JobNo, TOCRRESULTSEX **Results )
{
    return getresults( JobNo, TOCRGETRESULTS_EXTENDED, (void **)Results );
} // GetResults()


//--------------------------------------------------------
// Convert extended results to a string
BOOL FormatResults(TOCRRESULTSEX *Results, char *Msg)
{
    long            ItemNo;
    long            APos = 0;
    BOOL            Status = FALSE;

    if ( Results->Hdr.NumItems > 0 ) {
        for (ItemNo = 0; ItemNo < Results->Hdr.NumItems; ItemNo ++ ) {
            if ( Results->Item[ItemNo].OCRCha == '\r' )
                Msg[APos] = '\n';
            else
                Msg[APos] = (char)Results->Item[ItemNo].OCRCha;
            APos ++;
        }
        Msg[APos] = 0;
        Status = TRUE;
    }

    return Status;
} // FormatResults()


#pragma ENDDUMP
 
c:\fwh\samples\build.bat transym

Image

Now we need to create the import library...
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: 3rd party c wrapper functions for harbour

Post by reinaldocrespo »

Try with the files I've placed on the server. http://lac.structuredsystems.com/temp/ Here you will find the exported .lib from .dll as well as all other needed files. I get a clean build using Borland c++ 5.82.

You will probably have to comment the line that includes TOCRdll.h and instead create prototypes using harbour vm declarations. For example, this

Code: Select all

EXTERN_C long WINAPI TOCRInitialise(long *JobNo);
 
Needs to change to this:

Code: Select all

extern long TOCRInitialise(long *JobNo);
 
All this is done on Transym.prg on the available link above. If I don't fix prototypes this way then I always get missing functions when linking even when the .lib is being linked. If you find any other way to get it to work, please let me know.

Reinaldo.
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

Reinaldo,

> You will probably have to comment the line that includes TOCRdll.h and instead create prototypes using harbour vm declarations

This is not needed at all. The transym.prg that I have posted compiles fine using the TOCRdll.h header file

I have tried to create the import library using bcc 7 implib.exe but it failed, so I have created the TOCRdll.def by hand using this tool:
https://bitbucket.org/fivetech/fivewin- ... peinfo.exe

TOCRdll.def

Code: Select all

LIBRARY     TOCRDLL.DLL

EXPORTS

TOCRConvertFormat          @1
TOCRConvertTIFFtoDIB       @2
TOCRDoJob                  @3
TOCRDoJob2                 @4
TOCRDoJobPDF_EG            @5
TOCRDoJob_EG               @6
TOCRExtraInfGetMMF         @7
TOCRGetConfig              @8
TOCRGetConfigStr           @9
TOCRGetErrorMode           @10
TOCRGetFontName            @11
TOCRGetJobDBInfo           @12
TOCRGetJobResults          @13
TOCRGetJobResultsEx        @14
TOCRGetJobResultsEx_EG     @15
TOCRGetJobStatus           @16
TOCRGetJobStatusEx         @17
TOCRGetJobStatusEx2        @18
TOCRGetJobStatusMsg        @19
TOCRGetLicenceInfo         @20
TOCRGetLicenceInfoEx       @21
TOCRGetNumPages            @22
TOCRInitialise             @23
TOCRPopulateCharStatusMap  @24
TOCRRotateMonoBitmap       @25
TOCRSetConfig              @26
TOCRSetConfigStr           @27
TOCRSetErrorMode           @28
TOCRShutdown               @29
TOCRTWAINAcquire           @30
TOCRTWAINGetImages         @31
TOCRTWAINSelectDS          @32
TOCRTWAINShowUI            @33
TOCRWaitForAnyJob          @34
TOCRWaitForJob             @35
To create the import library from TOCRdll.def we do:
c:\bcc7\bin>implib TOCRdll.lib TOCRdll.def

Now the EXE is properly built:
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

There is something wrong with the DLL. If I try this:

Code: Select all

#include "FiveWin.ch"

function Main()

   MsgInfo( LoadLibrary( "TOCRdll.dll" ) )
   
return nil
I get a zero, which means an error loading the DLL.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Enrico Maria Giordano »

Reinaldo,

as I already wrote to you privately, the program compiles and links fine but when I run the EXE I get the error 0xc000007b.

Just a note: in C language, when you include a non standard header file (ie. a header file that is not one of the C standard header files) you have to use the syntax

Code: Select all

#include "nonstandard.h"
instead of

Code: Select all

#include <nonstandard.h>
EMG
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Enrico Maria Giordano »

Antonio Linares wrote:There is something wrong with the DLL. If I try this:

Code: Select all

#include "FiveWin.ch"

function Main()

   MsgInfo( LoadLibrary( "TOCRdll.dll" ) )
   
return nil
I get a zero, which means an error loading the DLL.
I suspected this...

EMG
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: 3rd party c wrapper functions for harbour

Post by Antonio Linares »

To check whats going on with the DLL I have created this simple test:

Code: Select all

#include "FiveWin.ch"

//----------------------------------------------------------------------------//

function Main()

   MsgInfo( Test( "TOCRdll.dll" ) )
   
return nil

//----------------------------------------------------------------------------//

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>

HB_FUNC( TEST )
{
   LoadLibrary( hb_parc( 1 ) );
   hb_retnl( GetLastError() );
}   

#pragma ENDDUMP
And I get error number 193:
ERROR_BAD_EXE_FORMAT
193 (0xC1)
%1 is not a valid Win32 application.
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply