Hi,
OE10.1BSP03
Win7 64bit
I need to call a procedure in an external DLL.
In the explanation of the DLL I find :
L_LTDOC_API L_INT L_DocStartUp(phDoc, pszEnginePath, bUseThunk)
L_HDOC * phDoc; | /* pointer to document handle to be updated */ |
L_TCHAR * pszEnginePath; | /* OCR engine location */ |
L_BOOL bUseThunk; | /* flag to determine to use thunk or not */ |
My problem is working with pointers and structures etc.
Here's my code :
DEF VAR L-status AS INT NO-UNDO.
DEF VAR L-memptr AS MEMPTR NO-UNDO.
SET-SIZE(L-memptr) = 1000. /* Why I use 1000, just guessing because I don't know what it should be */
PUT-STRING(L-memptr, 1) = "".
RUN L_DocStartUp(INPUT L-memptr, INPUT "", INPUT "FALSE", OUTPUT L-status).
MESSAGE L-status VIEW-AS ALERT-BOX.
PROCEDURE L_DocStartUp EXTERNAL "C:\Project\Scan\OCRProgress\LTDOCU.dll" CDECL PERSISTENT:
/*------------------------------------------------------------------------------
Purpose:
Parameters: <none>
Notes:
------------------------------------------------------------------------------*/
DEFINE INPUT PARAMETER P-handle AS MEMPTR.
DEFINE INPUT PARAMETER P-engine AS CHAR.
DEFINE INPUT PARAMETER P-thunk AS CHAR.
DEFINE RETURN PARAMETER P-status AS LONG.
END PROCEDURE.
After running this, I get the following error :
Microsoft Visual C++ Runtime Library
Runtime Error!
Program: C:\Progress\OpenEdge\bin\prowin32.exe
abnormal program termination
Can anyone give me some advice please ? Is there something wrong in my code ?
Kind regards,
Bart Syryn
Hello,
Here is some quick feedback.
The "abnormal program termination" error indicates that the execution of code in the DLL failed.
This could happen because the parameters are not valid.
Here are some things to check:
- Make sure that you are using the 32-bit version of LTDOCU.dll so it matches the 32-bit prowin32.exe.
- The documentation for L_DocStartUp - http://www.leadtools.com/help/leadtools/v175/ocr/api/dllref/l_docstartup.htm mentions that the signature for the function that you are using is
for V16 or later. Are you using V16 or later?
- The documentation shows bUseThunk as BOOL. You should define it as a LOGICAL in the ABL. (You need to make sure that the types match.)
- The example for L_DocStartUp shows that phDoc is a pointer to HDOC. You should allocate at least the same size as HDOC.
Otherwise, the function would try to write to memory that beyond the size of the memptr.
- Parameter pszEnginePath corresponds to the location of the OCR engine. You are passing empty string. The example shows NULL.
I wonder if using ? instead of "" would be better. Alternatively, you can pass the full path to the engine if you know what is the expected value.
Or you could define the parameter as LONG and pass 0 which corresponds to NULL.
(You might need to specify the path using double back slashes.)
I hope this helps.
Hello,
Thanks for the quick response.
I've looked at your feedback but still have some troubles with it. It's the first time I've tried calling an external procedure (other than kernel32.dll etc).
I'm using Leadtools SDK 17.5, so it's higher than 16 and L_DocStartUp needs three parameters.
LTDOCU.DLL is a 32bit DLL, they have also the 64bit DLL that is LTDOCX.dll, but I don't use it.
First problem is, how exactly do I need to use the parameter hDoc (that is a pointer).
DEF VAR L-memptr AS MEMPTR NO-UNDO.
SET-SIZE(L-memptr) = 1000.
PUT-STRING(L-memptr, 1) = "".
RUN L_DocStartUp(INPUT L-memptr, INPUT 0, INPUT "FALSE", OUTPUT L-status).
Is the above first parameter correct ?
Problem is also, I need to set the size of L-memptr, but I don't know what size it should be. That's the reason I took 1000.
For the third parameter (bUseThunk), I need a logical. But when I declare the procedure as follow :
PROCEDURE L_DocStartUp EXTERNAL "C:\Project\Scan\OCRProgress\LTDOCU.dll" CDECL PERSISTENT:
/*------------------------------------------------------------------------------
Purpose:
Parameters:
Notes:
------------------------------------------------------------------------------*/
DEFINE INPUT PARAMETER P-handle AS MEMPTR.
DEFINE INPUT PARAMETER P-engine AS LONG.
DEFINE INPUT PARAMETER P-thunk AS LOGICAL.
DEFINE RETURN PARAMETER P-status AS LONG.
END PROCEDURE.
I get a syntax error : 3383, DLL datatype can only be CHARACTER, BYTE, SHORT, UNSIGNED-SHORT, LONG, FLOAT or DOUBLE. How can I declare a logical ?
When I change in the DLL definition:
DEFINE INPUT PARAMETER P-thunk AS LOGICAL.
to
DEFINE INPUT PARAMETER P-thunk AS LONG.
And run it with :
RUN L_DocStartUp(INPUT L-memptr, INPUT 0, INPUT 0, OUTPUT L-status).
I get error 6069:
'C' call stack has been compromised after calling L_DocStartUp in C:\project\scan\OCRProgress\LTDOCU.dll (6069).
I don't know the path of the engine, so I pass 0, like you suggested.
Any help would be very appreciated.
Kind regards,
Bart Syryn
I am sorry.
When calling functions in a DLL you can only use some datatypes:
http://documentation.progress.com/output/OpenEdge102b/oe102bhtml/dvpin/wwhelp/wwhimpl/common/html/wwhelp.htm#href=19dvpinch12dll.21.1.html#642486&single=true
BOOL is defined as int
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx
typedef int BOOL;
Which is a 32-bit integer. In this case that you should use the compatible data type as specified in table Table 12–3 in the "Programming Interfaces" book which is LONG.
Hi,
Thanks again for the quick response.
Finaly I found the solution, I deleted CDECL in the declaration. And it worked fine....
Thanks for the link to the documentation about parameters and DLL. It will be helpfull.
Kind regards,
Bart Syryn