Page 1 of 2

3rd party c wrapper functions for harbour

PostPosted: Sat Mar 25, 2017 5:43 pm
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  Expand view

//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.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 8:11 am
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.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 8:23 am
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

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 8:24 am
by Antonio Linares
You must include:

#include <windows.h>

in order to use MessageBox()

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 8:46 am
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

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 2:50 pm
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  Expand view

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.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 5:19 pm
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

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 6:13 pm
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.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 6:25 pm
by Antonio Linares
This modified version is compiling clean:

transym.prg
Code: Select all  Expand view

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...

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 6:52 pm
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  Expand view

EXTERN_C long WINAPI TOCRInitialise(long *JobNo);
 


Needs to change to this:
Code: Select all  Expand view

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.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 7:30 pm
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-contributions/downloads/peinfo.exe

TOCRdll.def
Code: Select all  Expand view
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

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 7:48 pm
by Antonio Linares
There is something wrong with the DLL. If I try this:

Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

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


I get a zero, which means an error loading the DLL.

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 7:50 pm
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  Expand view
#include "nonstandard.h"


instead of

Code: Select all  Expand view
#include <nonstandard.h>


EMG

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 7:51 pm
by Enrico Maria Giordano
Antonio Linares wrote:There is something wrong with the DLL. If I try this:

Code: Select all  Expand view
#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

Re: 3rd party c wrapper functions for harbour

PostPosted: Sun Mar 26, 2017 7:58 pm
by Antonio Linares
To check whats going on with the DLL I have created this simple test:

Code: Select all  Expand view
#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/library/windows/desktop/ms681382(v=vs.85).aspx