gotomypc / leptonica

Automatically exported from code.google.com/p/leptonica
0 stars 0 forks source link

Apps created with VS2010 crash when linked to the Leptonica VS2008 DLL #45

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Using Visual Studio 2010, link ioformats_reg to the distributed VS2008 
generated leptonlib.dll

What is the expected output? What do you see instead?
I expect ioformats_reg to run successfully.
Instead ioformats_reg crashes.

What version of the product are you using? On what operating system?
leptonlib-1.67
Microsoft Visual Studio 2010
Windows XP Pro SP3.

Please provide any additional information below.
This issue is really the tip of the iceberg. See 
http://stackoverflow.com/q/4171403/506524 for more details.

ioformats_reg.c calls testcomp() which does:

    fp = fopen(filename, "rb");
    findFileFormat(fp, &format);

findFileFormat() is in readfile.c (linked into leptonlib.dll). The
very first thing it does (after some argument checks) is:

    rewind(fp);

and that's where the crash occurs.

"How to link with the correct C Run-Time (CRT) library" 
http://support.microsoft.com/kb/140584 says:

   A reusable library and all of its users should use the same CRT library types and therefore the same compiler switch...

   If you do choose to mix CRT libraries, remember that you have two separate copies of the CRT, with separate and distinct states, so you must be careful about what you try to do across a CRT-boundary. There are many ways to get into trouble with two CRTs. Here are just a few:

   * There are two separate heaps. You cannot allocate (explicitly with new, malloc, or so on -- or implicitly with strdup, strstreambuf::str, or so on), and then pass the pointer across a CRT-boundary to be freed.
   * You cannot pass a FILE* or file handle across a CRT-boundary and expect the "stdio low-level IO" to work.
   * You cannot set the locale in one and expect the other's locale to be set. 

The distributed leptonlib.dll is built with Visual Studio 2008 and thus uses 
the msvcr90.dll C-Runtime Library. Any application created by VS2010 on the 
other hand will use msvcr100.dll.

We are thus "mixing CRT libraries" and have to follow the restrictions just 
mentioned. The leptonica API has to be changed so any FILE handles or allocated 
memory it creates can only be manipulated/freed using the API.

For example, in ioformats_reg.c you can't have do fp = fopen(filename) and 
expect rewind(fp) to work in leptonlib.dll.

Also, there will be a problem with things like getLeptonlibVersion() and 
getImagelibVersions() wherein you allocate memory in leptonlib but give no way 
to free that memory (that I know of).

Original issue reported on code.google.com by tomp2...@gmail.com on 14 Nov 2010 at 6:19

GoogleCodeExporter commented 9 years ago
Thanks for bringing in this issue and for supporting all the
Windows users who have run into this (e.g., with Tesseract).

In 1.68 leptonica will provide wrappers for fopen(), fclose(), and free()
that can be used to assure that file stream and heap management
are all handled by the leponica dll.

So, for example, if leptonica returns a string on the heap,
the application can free it with lept_free().  Or if a file is
opened in the app, and the fp is passed to a leptonica function,
the app should use lept_fopen() and lept_fclose().

The programs in 'prog' that crash because of the use of two
different dll C-runtimes and heaps will be fixed.

Original comment by dan.bloo...@gmail.com on 20 Nov 2010 at 6:22

GoogleCodeExporter commented 9 years ago
fixed in 1.68

Original comment by dan.bloo...@gmail.com on 16 Mar 2011 at 12:06