1. How to call DLL with classes?
- Posted by TheresNoTime Sep 18, 2013
- 1543 views
I need to use DLL, that have got classes. How to do it? Some info from official documentation:
OCR( OCRSource(0, 0, 200, 100), OCRDest(), OCRDestFormat(dfText) );
class OCRSource { public: OCRSource(); OCRSource& BmpFile(const char *bmpFileName); OCRSource& Wnd(HWND); OCRSource& Rect(int ax, int ay, int bx, int by); };
class OCRDest { public: OCRDest(const char *destFileName); OCRDest(); const char *FileName; // NULL if the area is specified; otherwise, it is the destination file name void *Area; // NULL if the file name is specified; otherwise, it is the memory area int AreaSize; }; OCRExport OCRSuccess OCRDestFree(OCRDest&);
enum OCRDestFormat { dfText, dfRtf, dfVerbose, dfBinary, dfBmp };
2. Re: How to call DLL with classes?
- Posted by mattlewis (admin) Sep 18, 2013
- 1587 views
I need to use DLL, that have got classes. How to do it? Some info from official documentation:
C++ is not easy to use from a DLL. The reason for this is that C++ compilers mangle the names in order to add class and parameter and return type information to the exported symbols. It's possible to use these mangled names in your #define_c_func calls, and then typically you'd pass the this pointer as the first parameter, with the normal parameters following that. This is very fragile, however, as the mangling is different from compiler to compiler, even different versions of the same compiler. If you only need to call a few things, it might not be too bad.
An easier way is to write a thin C++ wrapper with an "extern C" interface. You'll need to add the this pointer as an explicit parameter. This is the approach I've taken with wxEuphoria. So for the following:
class OCRSource { public: OCRSource(); OCRSource& BmpFile(const char *bmpFileName); OCRSource& Wnd(HWND); OCRSource& Rect(int ax, int ay, int bx, int by); };
...you might wrap this as:
extern "C " { OCRSource * new_OCRSource(){ return new OCRSource(); } OCRSource & OCRSource_BmpFile( OCRSource &ocr, const char *bmpFileName ){ return ocr.BmpFile( bmpFileName ); } /* etc... */ }
...and then use it something like:
constant NEW_OCRSOURCE = define_c_func( OCR_DLL, "new_OCRSource", {}, C_POINTER ), OCRSOURCE_BMPFILE = define_c_func( OCR_DLL, "OCRSource_BmpFile", { C_POINTER, C_POINTER }, C_POINTER ) atom ocr = c_func( NEW_OCRSOURCE, {} ) atom file_ptr = allocate_string( "my.bmp" ) c_func( OCRSOURCE_BMPFILE, { ocr, file_ptr } ) -- etc...
Matt
3. Re: How to call DLL with classes?
- Posted by TheresNoTime Sep 18, 2013
- 1548 views
C++ is not easy to use from a DLL. The reason for this is that C++ compilers mangle the names in order to add class and parameter and return type information to the exported symbols. It's possible to use these mangled names in your #define_c_func calls, and then typically you'd pass the this## pointer as the first parameter, with the normal parameters following that. This is very fragile, however, as the mangling is different from compiler to compiler, even different versions of the same compiler. If you only need to call a few things, it might not be too bad.
By and large, I need the function "Rect" only.
An easier way is to write a thin C++ wrapper with an "extern C" interface.
Here's what I got, but it's just a dirty draft.
OCRSource src = new OCRSource(); OCRDest dst = new OCRDest(); extern "C" { void* getTextFromRect(int ax, int ay, int bx, int by) { src.Rect(ax, ay, bx, by); OCR(src, dst, 0); return dst.Area; } }
4. Re: How to call DLL with classes?
- Posted by ghaberek (admin) Sep 18, 2013
- 1589 views
Are you using Screen Scraping Library?
-Greg
5. Re: How to call DLL with classes?
- Posted by TheresNoTime Sep 18, 2013
- 1546 views
Are you using Screen Scraping Library?
-Greg
Apparently, it is, even though I downloaded it under another name and from another site - screenocrsdk.com
6. Re: How to call DLL with classes?
- Posted by TheresNoTime Sep 19, 2013
- 1469 views
It is not working yet. :( I have got error messages about names: OCR, OCRInit and OCRTerm. I uncomment in ocrsdk.h this line (may be, it is not enough).
#define OCRExport cdef __declspec(dllexport) //Not needed if all functions exported through .def file
#include "stdafx.h" #include "ocrsdk.h" #pragma comment(lib, "ocrsdk.lib") OCRSource* src = new OCRSource(); OCRDest* dst = new OCRDest(); OCRSuccess err = osOK; OCRExport void* getTextFromRect(int x, int y, int w, int h) { err = OCR( src->Rect(x, y, x+w, y+h), *dst, dfText ); if (err == osOK ) return dst->Area; return NULL; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: err = OCRInit(); break; case DLL_PROCESS_DETACH: err = OCRTerm(); } if (err == osOK) return TRUE; return FALSE; }
7. Re: How to call DLL with classes?
- Posted by mattlewis (admin) Sep 19, 2013
- 1457 views
It is not working yet. :( I have got error messages about names: OCR, OCRInit and OCRTerm. I uncomment in ocrsdk.h this line (may be, it is not enough).
It looks like you're using MSVC. I'm guessing that you're getting linking errors. Are you sure you're linking with the target dll?
You'll also probably have to put the initialization inside a function. To make it euphoria friendly, you'll need to put it in extern "C" brackets. Also...how do you tell it what to scan (i.e., src looks like it's always a blank whatever)? Maybe you just haven't gotten there yet.
Matt