Hi,

I am having an issue with creating a DLL with calls to (among other
things) the C standard library within.

I have reduced my problem to the following pieces of code:
/***************** dll.c ***************/
#include <stdio.h>
#include <stdlib.h>

int dt_read(FILE *f)
{
int status = EXIT_FAILURE;
char buf[100];

if (f != NULL)
{
if (NULL != fgets(buf, sizeof buf, f))
{
buf[sizeof buf - 1] = 0;
puts(buf);
status = EXIT_SUCCESS;
}
}
return status;
}
/****************** end of dll.c **************/

This code is compiled and linked into a DLL with the following .def file:

/*************** begin dll.def ****************/
LIBRARY DLL
DESCRIPTION "dll test dll"
VERSION 1.0
EXPORTS
dt_read
/*************** end dll.def *******************/

Then another application uses the code (dynamically linking to the DLL)
as follows:

#include <stdio.h>
#include <stdlib.h>

#include "dlltestdll.h"

int main(void)
{
int status = EXIT_FAILURE;
FILE *f;

f = fopen("main.c", "r");
if (NULL != f)
{
char buf[100];
if (NULL != fgets(buf, sizeof buf, f))
{
buf[sizeof buf - 1] = 0;
puts(buf);
}
status = dt_read(f);
}
fclose(f);

return status;
}

As the code shows, there are two similar calls to fgets, one from the
program itself, and the other one from the DLL. While the first call
succeeds, the second one fails somewhere deep into fgets. I can only
imagine that this is cause by some corruption due to bad calling
conventions, but am at lost as to how to correct/manage it. Any hints ?
--
Bertrand Mollinier Toublet
int main(){char*strchr();int j=1234;char t[]=":@abcdefghij-lmnopqrstuv"
"wxyz.\n",*i="iqgbgxmbbla.llsvoaz:zdxylaxejivnidhd@ttopnjeftuh-i";while
(*i){j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);}return 0;}

Re: DLL and calling convention by Joe

Joe
Mon Jul 28 16:28:29 CDT 2003

Greets,

Your best bet would be to link your DLL dynamically to the same threaded
version of the C run-time library. Do the same with your application as
well. This way, only one copy of the C run-time is used by your DLL and the
application and you won't have the problem of sharing different instances of
internal structures used by the run-time conflicting.

Regards,

Joe

"Bertrand Mollinier Toublet" <bertrand.molliniertoublet@enst-bretagne.fr>
wrote in message news:bg43qp$kpg9u$1@ID-168218.news.uni-berlin.de...
> Hi,
>
> I am having an issue with creating a DLL with calls to (among other
> things) the C standard library within.
>
> I have reduced my problem to the following pieces of code:
> /***************** dll.c ***************/
> #include <stdio.h>
> #include <stdlib.h>
>
> int dt_read(FILE *f)
> {
> int status = EXIT_FAILURE;
> char buf[100];
>
> if (f != NULL)
> {
> if (NULL != fgets(buf, sizeof buf, f))
> {
> buf[sizeof buf - 1] = 0;
> puts(buf);
> status = EXIT_SUCCESS;
> }
> }
> return status;
> }
> /****************** end of dll.c **************/
>
> This code is compiled and linked into a DLL with the following .def file:
>
> /*************** begin dll.def ****************/
> LIBRARY DLL
> DESCRIPTION "dll test dll"
> VERSION 1.0
> EXPORTS
> dt_read
> /*************** end dll.def *******************/
>
> Then another application uses the code (dynamically linking to the DLL)
> as follows:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> #include "dlltestdll.h"
>
> int main(void)
> {
> int status = EXIT_FAILURE;
> FILE *f;
>
> f = fopen("main.c", "r");
> if (NULL != f)
> {
> char buf[100];
> if (NULL != fgets(buf, sizeof buf, f))
> {
> buf[sizeof buf - 1] = 0;
> puts(buf);
> }
> status = dt_read(f);
> }
> fclose(f);
>
> return status;
> }
>
> As the code shows, there are two similar calls to fgets, one from the
> program itself, and the other one from the DLL. While the first call
> succeeds, the second one fails somewhere deep into fgets. I can only
> imagine that this is cause by some corruption due to bad calling
> conventions, but am at lost as to how to correct/manage it. Any hints ?
> --
> Bertrand Mollinier Toublet
> int main(){char*strchr();int j=1234;char t[]=":@abcdefghij-lmnopqrstuv"
> "wxyz.\n",*i="iqgbgxmbbla.llsvoaz:zdxylaxejivnidhd@ttopnjeftuh-i";while
> (*i){j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);}return 0;}
>



Re: DLL and calling convention by Bertrand

Bertrand
Mon Jul 28 17:28:19 CDT 2003

Doug Harrison [MVP] wrote:
>
> The problem is that the DLL function doesn't understand the FILE* you pass
> into it. You need to link the EXE and DLL to the same CRT DLL, so they'll
> share the same CRT state, which includes heap, file descriptors, and other
> things. For example, at the command line, you would use the -MD option to
> link to the release mode msvcrt.dll. Otherwise, if you link statically or to
> different CRT DLLs, each module has its own copy of the CRT, independent of
> all the rest, and you have to pay very close attention to module boundaries
> and never pass FILE*'s between modules, or have one module free memory
> malloc'd by another, etc.
>
Indeed. Thanks Doug and Joe. By the promptness of your answers, I gather
that my question was pretty much a FAQ. I did some research (though in
the wrong direction) before I posted here. Any Web resource I should
consult next time I have such a question ?

--
Bertrand Mollinier Toublet
"No sea vivo, Buendia" -- El presidente del tribunal,
in Cien anos de soledad, de Gabriel Garcia Marquez


Re: DLL and calling convention by Bob

Bob
Tue Jul 29 09:49:55 CDT 2003

On Mon, 28 Jul 2003 15:28:19 -0700, Bertrand Mollinier Toublet
<bertrand.molliniertoublet@enst-bretagne.fr> wrote:

>Any Web resource I should
>consult next time I have such a question ?

If you take a look at www.mvps.org, there's the "big list" of MVP
websites on there, which includes the MVP Visual C++ FAQ, and also my
own modest efforts.

There's always www.codeproject.com and www.codeguru.com, though the
fomer does seem to have gone desperately fashionable and be
concentrating more and more on C# these days, which is why I don't
visit any more :-)