Share C file across dll boundaries
-
Hello! I want to compile MuPDF as a dynamic library (dll) instead of a static library. With the static library, everthing works fine. However, the dll version is not working. When I call, e.g.
int f = _wopen(...);
read(f, ...);in the main app, everything works fine. However, if
read(f, ...);
is called inside the dll, I get an assertion. It seems to me that the file f is not known within the dll - therefore, the call to read(...) fails. Is there any way to share the files across dll boundaries? Alex
-
Hello! I want to compile MuPDF as a dynamic library (dll) instead of a static library. With the static library, everthing works fine. However, the dll version is not working. When I call, e.g.
int f = _wopen(...);
read(f, ...);in the main app, everything works fine. However, if
read(f, ...);
is called inside the dll, I get an assertion. It seems to me that the file f is not known within the dll - therefore, the call to read(...) fails. Is there any way to share the files across dll boundaries? Alex
LionAM wrote:
Is there any way to share the files across dll boundaries?
if your app and the DLL both are set to use the CRT in a shared library (not statically linked to the CRT), and are built to use the same version of the CRT (same compiler, CRT version, etc), it should work.
-
Hello! I want to compile MuPDF as a dynamic library (dll) instead of a static library. With the static library, everthing works fine. However, the dll version is not working. When I call, e.g.
int f = _wopen(...);
read(f, ...);in the main app, everything works fine. However, if
read(f, ...);
is called inside the dll, I get an assertion. It seems to me that the file f is not known within the dll - therefore, the call to read(...) fails. Is there any way to share the files across dll boundaries? Alex
LionAM wrote:
I get an assertion.
Which one?
LionAM wrote:
the file f is not known within the dll
Where is it defined in the DLL code?
Unrequited desire is character building. OriginalGriff I'm sitting here giving you a standing ovation - Len Goodman
-
LionAM wrote:
I get an assertion.
Which one?
LionAM wrote:
the file f is not known within the dll
Where is it defined in the DLL code?
Unrequited desire is character building. OriginalGriff I'm sitting here giving you a standing ovation - Len Goodman
Thank you for the answer. In the MuPDF sample, the file is opened with
int fd = _wopen(filename, _O_BINARY | _O_RDONLY, 0666);
The file descriptor
fd
is passed to a function defined within libmupdf. However, when this function tries to read the file (inside libmupdf):read(fd, buf, bufsize)
the function fails with the assertion
---------------------------
Microsoft Visual C++ Debug LibraryDebug Assertion Failed!
Program: p:\OLE_PDF\Debug\OLE_PDF_Test.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\read.c
Line: 86Expression: (_osfile(fh) & FOPEN)
I think the proble is that the libmupdf.dll "lives" in a different address space - you cannot simply assume that resources are valid inside the dll and the exe. Therefore, I changed the MuPDF sample so that the file is opened inside the library. Now the file is read as expected. However, there are still other (perhaps similar problems). For example, there are global variables inside libmupdf:
static fz_colorspace k_device_bgr = { -1, "DeviceRGB", 3, bgr_to_rgb, rgb_to_bgr };
fz_colorspace *fz_device_bgr = &k_device_bgr;In the library header (which is included in the MuPDF sample), it is declared as
extern fz_colorspace *fz_device_bgr;
Inside the MuPDF sample, there is a local variable
fz_colorspace *colorspace = fz_device_bgr;
It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that
fz_device_bgr
has different values inside the dll and inside the sample (where it is undefinded?). Alex -
Thank you for the answer. In the MuPDF sample, the file is opened with
int fd = _wopen(filename, _O_BINARY | _O_RDONLY, 0666);
The file descriptor
fd
is passed to a function defined within libmupdf. However, when this function tries to read the file (inside libmupdf):read(fd, buf, bufsize)
the function fails with the assertion
---------------------------
Microsoft Visual C++ Debug LibraryDebug Assertion Failed!
Program: p:\OLE_PDF\Debug\OLE_PDF_Test.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\read.c
Line: 86Expression: (_osfile(fh) & FOPEN)
I think the proble is that the libmupdf.dll "lives" in a different address space - you cannot simply assume that resources are valid inside the dll and the exe. Therefore, I changed the MuPDF sample so that the file is opened inside the library. Now the file is read as expected. However, there are still other (perhaps similar problems). For example, there are global variables inside libmupdf:
static fz_colorspace k_device_bgr = { -1, "DeviceRGB", 3, bgr_to_rgb, rgb_to_bgr };
fz_colorspace *fz_device_bgr = &k_device_bgr;In the library header (which is included in the MuPDF sample), it is declared as
extern fz_colorspace *fz_device_bgr;
Inside the MuPDF sample, there is a local variable
fz_colorspace *colorspace = fz_device_bgr;
It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that
fz_device_bgr
has different values inside the dll and inside the sample (where it is undefinded?). AlexLionAM wrote:
It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that
fz_device_bgr
has different values inside the dll and inside the sample (where it is undefinded?).You can't access the main application's globals from a dll like that. They would have to be passed using a regular function call (perhaps using
Get()
andSet()
calls). -
LionAM wrote:
It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that
fz_device_bgr
has different values inside the dll and inside the sample (where it is undefinded?).You can't access the main application's globals from a dll like that. They would have to be passed using a regular function call (perhaps using
Get()
andSet()
calls).Thank you for the answer. After correcting this issue (by calling a dll function which returns the dll "version" of colorspace variable), the program does not crash any more. However, it is still not working as expected... I have to search further for similar issues, which becomes more difficult as I don't know where to look for the problem. I think I will debug both the statically and the dynamically linked versions simultaneously and look where they behave different... Alex
-
Thank you for the answer. After correcting this issue (by calling a dll function which returns the dll "version" of colorspace variable), the program does not crash any more. However, it is still not working as expected... I have to search further for similar issues, which becomes more difficult as I don't know where to look for the problem. I think I will debug both the statically and the dynamically linked versions simultaneously and look where they behave different... Alex
For all global variables defined in the dll header, I defined a function (inside the dll) which returns the value/address of the corresponding global variable. These functions are called from the sample app instead of trying to access the global variables. Now, the dll seems to work - I can render my pdf files. Alex
-
For all global variables defined in the dll header, I defined a function (inside the dll) which returns the value/address of the corresponding global variable. These functions are called from the sample app instead of trying to access the global variables. Now, the dll seems to work - I can render my pdf files. Alex
If you're passing arguments by reference to/from a dll, remember that the safest thing to do is to allocate/deallocate within the same binary. In another words, don't allocate something in the dll and try to deallocate it within the executable (or the other way around).
-
If you're passing arguments by reference to/from a dll, remember that the safest thing to do is to allocate/deallocate within the same binary. In another words, don't allocate something in the dll and try to deallocate it within the executable (or the other way around).