<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">While I've done a lot of C programming that is useful for FFI interfacing, I've not done much C++.  So just sharing something new I learnt today to help with FFI interfacing to combined C/C++ libraries.  I thought maybe others in the same boat could be interested in this.</div><div dir="ltr">[Original question asked in squeak-dev, cross-posting to pharo-dev]<br></div><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Fri, 2 Nov 2018 at 21:06, Ben Coman <<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Fri, 2 Nov 2018 at 18:44, Edwin Ancaer <<a href="mailto:eancaer@gmail.com" target="_blank">eancaer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>As I'm looking at a way to automate the search of documents in my humble administration, I read some articles about OCR. I came along an article about using Python with Tesseract, to transform an scan of a document into text, that is searchable. <br></div><div><br></div><div>My question now is if I can do something similar with Squeak. To my inexperienced eye, it seems like I should use FFI to call the functions in the Tesseract API, but this API is in  C++, and I don't know if it is possible to use FFI to call C++ functions?</div></div></blockquote><div><br></div><div>You are right C++ is difficult because of the name mangling of function symbols, </div><div>but good fortune I notice Tesseract has C bindings...</div><div>    <a href="https://github.com/tesseract-ocr/tesseract#for-developers" target="_blank">https://github.com/tesseract-ocr/tesseract#for-developers</a><br></div><div>    <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/capi.h" target="_blank">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/capi.h</a></div><div>so it looks like you are in the clear.</div></div></div></div></div></blockquote><div><br></div><div>Browsing a deeper I got quite confused for a while. </div><div>I could see a typedef definition for TessResultRenderer here... <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/capi.h#L83" target="_blank">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/capi.h#L83</a></div><div>      "typedef struct TessResultRenderer TessResultRenderer"  </div><div>which I understood to must refer to *existing* struct, but I couldn't find the definition of that struct anywhere. In particular...</div><div>   $ git clone git@github.com:tesseract-ocr/tesseract.git </div><div>   $ cd tesseract</div><div>   $ find . -type f -name "*h" -exec grep -Hn TessResultRenderer {} \;</div><div>but didn't find any struct definitions.</div><div><br></div><div>I could only find TessResultRenderer as a class definition... <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L45-L139" target="_blank">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L45-L139</a></div><div>and the only thing that I guessed could possibly make sense was that C++ classes and structs could be used interchangeably.  My google-fu failed to find anything useful, so an experiment...</div><div><div>$ vi test.cpp</div><div>        #include <stdio.h></div><div>        class SomeClass {</div><div>          public:</div><div>            int a;</div><div>            int b;</div><div>        };</div><div>        typedef struct SomeClass SomeTypeDef;</div><div>        int main()</div><div>        {</div><div>                SomeTypeDef x;</div><div>                x.a = 5;</div><div>                x.b = 7;</div><div>                printf("Answer is %d\n", x.a + x.b);</div><div>        }</div></div><div>$ gcc test.cpp</div><div>$ ./a.out</div><div>Answer is 12</div><div><br></div><div>Now I noticed that the TessResultRenderer member variables were private... <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L131-L139">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L131-L139</a></div><div>and curious about that I changed my test example from public to private</div><div>which somewhat expectedly produced compile errors. </div><div><br></div><div>So those TessResultRenderer member variables must only be accessed from a member function, but how is that C++ member function called from C to operate on a particular object?</div><div>An example is TessResultRendererInsert...  </div><div>    C Declaration: <a href="https://github.com/tesseract-ocr/tesseract/blob/c375f4fbf73b8f761b2e65e0e3ad6776b9fbee78/src/api/capi.h#L135">https://github.com/tesseract-ocr/tesseract/blob/c375f4fbf73b8f761b2e65e0e3ad6776b9fbee78/src/api/capi.h#L135</a><br></div><div>    C Definition: <a href="https://github.com/tesseract-ocr/tesseract/blob/c375f4fbf73b8f761b2e65e0e3ad6776b9fbee78/src/api/capi.cpp#L90-L93">https://github.com/tesseract-ocr/tesseract/blob/c375f4fbf73b8f761b2e65e0e3ad6776b9fbee78/src/api/capi.cpp#L90-L93</a><br></div><div>    C++ Declaration: <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L52">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.h#L52</a></div><div>    C++ Definition: <a href="https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.cpp#L59-L70">https://github.com/tesseract-ocr/tesseract/blob/master/src/api/renderer.cpp#L59-L70</a></div><div><br></div><div>So in the C Defintion "the C++ member-function insert() as being called via a function pointer in the struct." (is that a reasonable way to describe it?)</div><div><br></div><div>In this case, because of the private member variables, our FFI would treat TessResultRenderer as an opaque object, which simplifies things.  I would guess in-Image direct access to the member variables from would need to account for the offset due to variables holding the function pointer to the member functions.</div><div><br></div><div>cheers -ben</div><div><br></div><div><br></div><div>P.S. for Tesseract FFI it might be good to start with reproducing this example...</div><div><div><a href="https://github.com/tesseract-ocr/tesseract/wiki/APIExample#example-using-the-c-api-in-a-c-program" target="_blank">https://github.com/tesseract-ocr/tesseract/wiki/APIExample#example-using-the-c-api-in-a-c-program</a> </div><br class="gmail-Apple-interchange-newline"></div><div><br></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>