Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Can't find _sprintf in msvcrt.dll



Permlink Replies: 3 - Last Post: Oct 14, 2014 10:10 AM Last Post By: Remy Lebeau (Te...
Jonathan Neve

Posts: 14
Registered: 4/12/08
Can't find _sprintf in msvcrt.dll
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2014 1:24 PM
Hello all,

I've got a problem and I wonder if anyone else has encountered it. We
are in the process of converting a massive legacy project (over 1200
forms) from C++Builder 5 to Delphi XE6. After a considerable effort of
getting all the third party components installed and all the code
translated from C++ to object pascal, we at last have it compiling.

Unfortunately, when we try to run it, we get an error saying that
_sprintf cannot be found in msvcrt.dll. Presumably, this must be coming
from some third-party component, since we definitely have never used
sprintf directly (or if we did, it was changed during the translation).

The strange thing is that it's looking for "_sprintf" whereas the
correct name exported by msvcrt.dll seems to be "sprintf" without the
underscore. I've done an exhaustive grep search through all the 3rd
party components we have installed, and have only found that there is
some reference to sprintf in a file in the Jcl (zlibh.pas), but even
after I comment out the line and recompile the Jcl, I still get the problem.

Does anyone have any idea what could be causing this?

Thanks in advance,
Jonathan Neve
http://www.copycat.fr
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Can't find _sprintf in msvcrt.dll
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2014 2:32 PM   in response to: Jonathan Neve in response to: Jonathan Neve
Jonathan wrote:

The strange thing is that it's looking for "_sprintf" whereas the correct
name exported by msvcrt.dll seems to be "sprintf" without the underscore.

In C++, you use a .LIB file to statically link to a DLL function. The C++
compiler decorates a __cdecl function with a leading underscore by default,
you would have to use extern "C" or a .DEF file to override that. The IMPLIB
tool has an option to generate an alias with a leading underscore for DLL
functions that use __cdecl when creating a .LIB file. So whatever code is
trying to use sprintf() is likely linking to the .LIB file without that extra
alias available.

Delphi does not use a .LIB file to statically link to a DLL function. An
DLL function name is specified in code, via the 'name' attribute of the 'external'
keyword if it is exported with decoration. If the problem were originating
from Pascal code, an import of sprintf() would have to be explicitly specifying
'_sprintf' as the DLL function name being imported.

I've done an exhaustive grep search through all the 3rd party components
we have installed, and have only found that there is some reference to
sprintf in a file in the Jcl (zlibh.pas), but even after I comment out the
line and recompile the Jcl, I still get the problem.

Pascal-written components work the same in C++Builder as they do in Delphi,
so if this was a coding problem inside a component, your C++Builder project
should have been affected as well. So the problem has to be coming from
somewhere else.

--
Remy Lebeau (TeamB)
Jonathan Neve

Posts: 14
Registered: 4/12/08
Re: Can't find _sprintf in msvcrt.dll
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 14, 2014 12:32 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy,

Thanks for your helpful answer!

Le 13/10/14 23:32, Remy Lebeau (TeamB) a Ă©crit :
Jonathan wrote:

The strange thing is that it's looking for "_sprintf" whereas the correct
name exported by msvcrt.dll seems to be "sprintf" without the underscore.

In C++, you use a .LIB file to statically link to a DLL function. The C++
compiler decorates a __cdecl function with a leading underscore by default,
you would have to use extern "C" or a .DEF file to override that. The IMPLIB
tool has an option to generate an alias with a leading underscore for DLL
functions that use __cdecl when creating a .LIB file. So whatever code is
trying to use sprintf() is likely linking to the .LIB file without that extra
alias available.

But all my code is now written in Delphi : there's no C++ code left. I
do have .lib files for all my 3rd party components (for C++Builder
support), but presumably, the Delphi compiler isn't using them.

Pascal-written components work the same in C++Builder as they do in Delphi,
so if this was a coding problem inside a component, your C++Builder project
should have been affected as well. So the problem has to be coming from
somewhere else.

Ok, that makes sense. Except that we did upgrade all our components,
since we were obviously using much older versions under BCB 5 than we
are now using in XE6. So it's hard to compare...

But is there any way to tell which parts of the source are causing the
dependency? Where should I look to find the list of DLLs that are
statically linked in my EXE? Is there any was to tell on a per-unit
basis, so that we could see which units are causing the dependency?

Thanks,
Jonathan Neve
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Can't find _sprintf in msvcrt.dll
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 14, 2014 10:10 AM   in response to: Jonathan Neve in response to: Jonathan Neve
Jonathan wrote:

But is there any way to tell which parts of the source are causing
the dependency?

A grep should have told you that, unless you are using a component that you
don't have source for, or if you are using a component that internally uses
pre-compiled OBJ files.

Where should I look to find the list of DLLs that are statically linked
in my EXE?

You can use the TDUMP command-line tool to look at the EXE's Imports table,
but that will not tell you which unit is linking to which DLL function.

Is there any was to tell on a per-unit basis, so that we could see
which units are causing the dependency?

You would likely have to find a third-party DCU dumper tool to look at which
DCU links to which DLL function.

BTW, I just discovered (thanks to Rudy Velthuis) that XE2 introduced a new
System.Win.Crtl.pas unit that declares commonly-used functions from msvcrt.dll,
including sprintf(), with both leading-underscore and non-leading-underscore
versions. So if any Delphi code in your app or components did happen to
link to sprintf() directly, it should probably be updated to use the System.Win.Crtl
unit instead.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02