Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working on Mono #23

Closed
Gankov opened this issue May 26, 2013 · 21 comments
Closed

Working on Mono #23

Gankov opened this issue May 26, 2013 · 21 comments
Milestone

Comments

@Gankov
Copy link

Gankov commented May 26, 2013

If i right understand this library don't work on mono, because embedded libtesseract302.dll library request kernel32 which has not in mono.
But tesseract works on Linux.
My question:
Do you have plan to make mono compatibility?
Is this possible make to on no windows os instead load embedded dll, load system tesseract library like libtesseract.so.3?

@charlesw
Copy link
Owner

That's certainly an option, I'll look into it next weekend if I have time.

@charlesw
Copy link
Owner

Can you see if this works now? You'll need to comment out all calls to WindowsLibraryLoader.LoadLibrary first.

@Gankov
Copy link
Author

Gankov commented May 30, 2013

It is works on Windows and don't work on Linux.
I am not understand how it will work on Linux with current implementation. What do i need comment out?
If i will need write code that load linux library, that ok. I will try implement it after end work on using tesseract in my application at least for windows.
I think if wrapper library runs on linux, it need to load linux library from /usr/lib64/libtesseract.so.3.0.2
if it running on windows need to load dll.
I didn't write cross-platform wrappers before, and don't know how it should be implemented.

@charlesw
Copy link
Owner

Ok I understand, for now you'll need to comment out the loadlibrary routines I mentioned previously this is to prevent it loading the libs using the win32 libs. I'm also assuming that mono can resolve the tesseract libraries and get the right version. If you've got this far already and still having issues its likely either an x86 or x64 issue or the given method Isn't been invoked correctly by mono. Were you able to invoke the getversion method this might be a good way to tell if the library was loaded correctly.

@AndreyAkinshin
Copy link
Contributor

Hi, charlesw!

I think, the Mono support is a great feature. Maybe the following way will be useful:
http://dimitry-i.blogspot.ru/2013/01/mononet-how-to-dynamically-load-native.html
What do you think?

@charlesw
Copy link
Owner

Looks promising, do you want to give it a go?
On 22 May 2014 20:30, "Andrey Akinshin" notifications@github.com wrote:

Hi, charlesw!

I think, the Mono support is a great feature. Maybe the following way will
be useful:

http://dimitry-i.blogspot.ru/2013/01/mononet-how-to-dynamically-load-native.html
What do you think?


Reply to this email directly or view it on GitHubhttps://github.com//issues/23#issuecomment-43871475
.

@AndreyAkinshin
Copy link
Contributor

Yes, I will do it.

@AndreyAkinshin
Copy link
Contributor

Unfortunately, I could not find a beautiful solution based on the DllImport attribute because of Mono and Microsoft .NET Runtime have different algorithms that work with native libraries. So, I developed own approach: we can generate calls of native method on the fly by signatures from some interface. Please take, a look at my solution: https://github.com/AndreyAkinshin/DotNetRuntimeImplementer
If you like this approach, I can modify it to your needs.

@charlesw
Copy link
Owner

Looks good, I'd probably like to see the function delegates you create in
InteropRuntimeImplementer.InvokeMethod being cached.

Also how are you handling parameter and result Marshalling?

Also while I do realise that mono and .net have different algorithms for
loading unmanaged libraries I thought the dllimport technic would have
worked on both platforms provided the library name was the same which
should be the case since the extention is left off. What was the issue that
you ran into that prevented it from working?

Unfortunately, I could not find a beautiful solution based on the DllImport
attribute because of Mono and Microsoft .NET Runtime have different
algorithms that work with native libraries. So, I developed own approach:
we can generate calls of native method on the fly by signatures from some
interface. Please take, a look at my solution:
https://github.com/AndreyAkinshin/DotNetRuntimeImplementer
If you like this approach, I can modify it to your needs.


Reply to this email directly or view it on GitHub
#23 (comment).

@AndreyAkinshin
Copy link
Contributor

I'd probably like to see the function delegates you create in InteropRuntimeImplementer.InvokeMethod being cached.

What do you mean?

Also how are you handling parameter and result Marshalling?

I do it via IL commands. Please check out method RuntimeImplementer.ImplementMethods.

What was the issue that you ran into that prevented it from working?

There are several problems.
First: MS.NET Runtime used loaded in memory assemblies for resolving DllImport. Mono don't. So, approach with LoadLibrary don't work in Mono.
Second: let's consider an example. We have the x86 architecture. The tesseract wrapper says: “I want to use native method from DllImport["x86/libtesseract302.dll"]”. Mono says: “Ok”. The native libtesseract302 library says: “I want to use liblept168.dll for native needs”. Mono says: “I will look for liblept168.dll in the root direcory. Oops, there is no file ./liblept168.dll”. Unfortunately, even DllMap can't solve the problem with native dependences (anyway, I could not get to do it). So, the only way is load the target library handle, load the target method address (GetProcAddress) and explicitly use it. But explicitly using is a very ugly way. So, I generate the target logic on the fly with IL commands using signature from declared interface. The result code is very similar to this approach.

Sorry for my bad English. Please, feel free to ask any additional questions.

@charlesw
Copy link
Owner

Thanks for the quick response. All up looks like a very nice approach to
getting support for mono and dotnet in one assembly.

Do you want to have a look at adding this to this library? Let me know if
there is anything I can do to help.

Charles
On 16 Jul 2014 17:34, "Andrey Akinshin" notifications@github.com wrote:

I'd probably like to see the function delegates you create in
InteropRuntimeImplementer.InvokeMethod being cached.

What do you mean?

Also how are you handling parameter and result Marshalling?

I do it via IL commands. Please check out method
RuntimeImplementer.ImplementMethods.

What was the issue that you ran into that prevented it from working?

There are several problems.
First: MS.NET Runtime used loaded in memory assemblies for resolving
DllImport. Mono don't. So, approach with LoadLibrary don't work in Mono.
Second: let's consider an example. We have the x86 architecture. The
tesseract wrapper says: “I want to use native method from
DllImport["x86/libtesseract302.dll"]”. Mono says: “Ok”. The native
libtesseract302 library says: “I want to use liblept168.dll for native
needs”. Mono says: “I will look for liblept168.dll in the root direcory.
Oops, there is no file ./liblept168.dll”. Unfortunately, even DllMap
http://www.mono-project.com/Config_DllMap can't solve the problem with
native dependences (anyway, I could not get to do it). So, the only way is
load the target library handle, load the target method address (
GetProcAddress) and explicitly use it. But explicitly using is a very
ugly way. So, I generate the target logic on the fly with IL commands using
signature from declared interface. The result code is very similar to this
approach
http://dimitry-i.blogspot.ru/2013/01/mononet-how-to-dynamically-load-native.html
.

Sorry for my bad English. Please, feel free to ask any additional
questions.


Reply to this email directly or view it on GitHub
#23 (comment).

@AndreyAkinshin
Copy link
Contributor

Ok, I'll try. Can you give me Unix binary files for the native tesseract library and the native leptonica library? (x86 and x64 versions)

@charlesw
Copy link
Owner

If by Unix you mean a linux distro like Ubuntu I think you can just use the
package manager. The package is called tesseract-ocr.

E.g. http://packages.ubuntu.com/search?keywords=tesseract-ocr
On 17 Jul 2014 20:34, "Andrey Akinshin" notifications@github.com wrote:

Ok, I'll try. Can you give me Unix binary files for the native tesseract
library and the native leptonica library? (x86 and x64 versions)


Reply to this email directly or view it on GitHub
#23 (comment).

@AndreyAkinshin
Copy link
Contributor

Ok.

@AndreyAkinshin
Copy link
Contributor

Great news! My approach works with Tesseract. Now, I am preparing a pull-request for you. What branch should I use?

Also there is an issue about Linux support. It's about locale: we should use "LC_ALL=C" for normal work. In the other case, the native Tesseract library gives an error: Error: Illegal min or max specification!. You can read more about the issue here and here (look to the initialize_tesseract function). Do you now, how we can fix it from C# source code?

@charlesw
Copy link
Owner

Excellent, use the dev branch.

I'll have a look at the LC-ALL issue tomorrow.
On 18 Jul 2014 20:11, "Andrey Akinshin" notifications@github.com wrote:

Great news! My approach works with Tesseract. Now, I am preparing a
pull-request for you. What branch should I use?

Also there is an issue about Linux support. It's about locale: we should
use "LC_ALL=C" for normal work. In the other case, the native Tesseract
library gives an error: Error: Illegal min or max specification!. You can
read more about the issue here
https://code.google.com/p/tesseract-ocr/issues/detail?id=910 and here
https://github.com/zdenop/pyTesseractDemo/blob/master/pyTesseractDemo.py
(look to the initialize_tesseract function). Do you now, how we can fix
it from C# source code?


Reply to this email directly or view it on GitHub
#23 (comment).

@charlesw
Copy link
Owner

In regards to the LC-ALL issue you should be able to implement the
recommend workaround for 3.02 by calling setlocale. A quick search
indicates it lives in libc.so or similar.
On 18 Jul 2014 20:20, "Charles Weld" charles.weld@gmail.com wrote:

Excellent, use the dev branch.

I'll have a look at the LC-ALL issue tomorrow.
On 18 Jul 2014 20:11, "Andrey Akinshin" notifications@github.com wrote:

Great news! My approach works with Tesseract. Now, I am preparing a
pull-request for you. What branch should I use?

Also there is an issue about Linux support. It's about locale: we should
use "LC_ALL=C" for normal work. In the other case, the native Tesseract
library gives an error: Error: Illegal min or max specification!. You
can read more about the issue here
https://code.google.com/p/tesseract-ocr/issues/detail?id=910 and here
https://github.com/zdenop/pyTesseractDemo/blob/master/pyTesseractDemo.py
(look to the initialize_tesseract function). Do you now, how we can fix
it from C# source code?


Reply to this email directly or view it on GitHub
#23 (comment).

@AndreyAkinshin
Copy link
Contributor

Unfortunately, I found one more issue with my library. Now I don't have complete support of ref parameters. My solution works fine with Mono (Ubuntu and Windows), but it crashs on MS .NET Runtime. So, I need more time to improve my library. I think I will have a working solution on the next week.

@AndreyAkinshin
Copy link
Contributor

Great news! I developed new version of my library without relfection issues. Also now we can not worry about caching: I rewrote IL generation and now signature implements directly to native call. The pull-request will be soon.

@AndreyAkinshin
Copy link
Contributor

New version of the library: InteropDotNet
Pull-request: #107

@charlesw
Copy link
Owner

charlesw commented Aug 2, 2014

Merged changes into main dev branch and mono support will be in the next release. Thanks.

@charlesw charlesw closed this as completed Aug 2, 2014
@charlesw charlesw added this to the 1.1 - Tesseract 3.03 support milestone Aug 2, 2014
@charlesw charlesw mentioned this issue Jun 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants