msvcp71.dll and Python 2.4 C++ extensions

"Martin v. Löwis" martin at v.loewis.de
Tue Feb 8 15:40:21 EST 2005


Matthias Baas wrote:
> I'm creating the installer via the distutils by calling "setup.py
> bdist_wininst". How can I configure distutils to have it create an
> installer that does the above things?

Ah, I see. Unfortunately, bdist_wininst is not capable of doing
a Windows logo compliant installation (with proper versioning checks,
shared dll reference count, etc) of a DLL. You will have to find
a different technology to distribute your application - or make sure
you copy the DLL in a place where it previously did not exist.

> How should an installer check if a DLL is already present? 

It should check if the file exists. If it exists, it should check
the version number of the file (there are APIs for that available),
and if the language of the installed DLL differs from the language
of the package's DLL. If the new DLL is somehow "better" (newer
version, or same version, different language, and user requested
overwriting), it should replace the DLL.

 > Are DLLs registered with Windows so I can query a database?

To some degree. If the software is uninstalled, the installer should
remove the file. If the file was already present at installation time,
removal may break other software. Therefor, there is a registry entry
for each path name that is a reference count, under

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs

If you expect that the file is already there, you need to use that
mechanism.

> Or should the
> installer search for the DLL in the directories specified in the PATH
> variable and see if the DLL is there?

No. There is no problem at all to install the same DLL multiple times,
in different places. In fact, Microsoft discourages shared DLLs, and
recommends that each package should install its own copy.

Windows will look for a DLL in
- the directory of the EXE
- the current working directory
- system32
- windows
- PATH

In your case, putting the C++ DLL into the directory containing
python.exe might be sufficient. The safest thing, of course, is to
put the DLL into system32 - in which case you *have* to install it
shared.

> "An application should use and redistribute msvcr71.dll, and it should
> avoid placing a copy or using an existing copy of msvcr71.dll in the
> system directory. Instead, the application should keep a copy of
> msvcr71.dll in its application directory with the program executable."

Yes. This means to install it into the directory containing python.exe.
Unfortunately, this does not work if your extension is then used in
an embedded Python, e.g. one running as a COM object. In this case,
python.exe will not be the main executable, but, say, outlook.exe will
be. So Microsoft's recommendation to install the DLL into the EXE
directory is flawed for COM and other embedded cases. This is
precisely the reason why the Python installer installs both python24.dll
and msvcr71.dll into system32.

> Well, yes, I know. But I don't see Python as a standalone application.
> One of the great things about Python is that there are so many
> extension modules for every kinds of purposes. So, making available
> the C++ runtime would just pave the way for more of those extension
> modules by making it easier to distribute binary packages that are
> implemented in C++.

I think we agree that building and running such an extension is not
a problem - it just works.

Distributing such an extension is indeed a problem, as bdist_wininst
does not support this case properly.

I'll plan to write a bdist_msi one day, which should handle DLL
installation better as much of the magic required is built into
Windows Installer.

> I was referring to the possibility that the DLL might get installed
> several times at several different locations which would be a waste of
> disk space. If there's only one file, then I agree with the above
> (however, what happens if I uninstall one package and this package
> removes the DLL even when there are other packages installed that
> still require the DLL?).

The other packages will also have added to the shared reference counter.
Uninstalling will only DECREF the counter, and the file will be removed
only when the counter goes to zero.

> For one smaller package I was compiling I solved the problem by
> linking against the static versions of the C/C++ runtime. This will
> also satisfy the "It-Should-Just-Work" constraint... :)  (however,
> there still could be situations where this is not possible (the
> sources might not be available, for example)).

You should make sure to use the DLL version of the C runtime. Otherwise,
you will be mixing multiple C runtimes (one that python24.dll links
with, and one linked statically into your extension); this might cause
troubles (such as memory leaks and crashes).

Regards,
Martin



More information about the Python-list mailing list