Title: ctypes.util.find_msvcrt() function
Type: enhancement Stage:
Components: Extension Modules Versions: Python 2.6
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: theller Nosy List: amaury.forgeotdarc, christian.heimes, theller
Priority: normal Keywords: patch

Created on 2008-01-11 14:59 by theller, last changed 2008-05-16 20:13 by theller. This issue is now closed.

File name Uploaded Description Edit
ctypes-util.patch theller, 2008-01-11 14:59 Patch for Lib\ctypes\
Messages (7)
msg59713 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2008-01-11 14:59
I'm uploading this patch for discussion, in case someone cares.

This code (for Windows) adds a function ctypes.util.find_msvcrt().  This
function returns the filename of the MSVC runtime library that the
current Python executable uses.  If calling functions from the C runtime
library, it is very important to use the SAME dll that Python uses.

Further, this patch changes ctypes.util.find_library(name) so that the
MSVC runtime library name is returned when searching for "c" or "m".
msg59728 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-01-11 17:41
In general I like the idea. But wouldn't it be better to have a cross
platform function which returns the c runtime library? msvcrt?? on
Windows, libc on Linux and whatever Mac and BSD are using.
msg59732 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2008-01-11 18:27
The cross-platform function is ctypes.util.find_library, which is
currently not very useful on Windows.

This patch changes it so that, on Windows, find_library("c") or
find_library("m") finds the MS C runtime lib which exposes functions the
are typically in libc and libm.

The runtime lib in Windows is special anyway; the 'open' function, for
example, is exported as '_open'.

However, the easiest way on Linux (don't know about other platforms) to
load the C runtime lib is to use ctypes.CDLL(None), which translates to
dlopen(NULL) in C.  Linux exposes all symbols from all loaded libraries
to the returned handle.
msg59963 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-01-15 12:42
I found the code I wrote some time ago for the same purpose:
(in pypy, which uses ctypes a lot)

import sys
if sys.platform == 'win32':
    # Parses sys.version and deduces the version of the compiler
    import distutils.msvccompiler
    version = distutils.msvccompiler.get_build_version()
    if version is None:
        # This logic works with official builds of Python.
        if sys.version_info < (2, 4):
            clibname = 'msvcrt'
            clibname = 'msvcr71'
        if version <= 6:
            clibname = 'msvcrt'
            clibname = 'msvcr%d' % (version * 10)

    # If python was built with in debug mode
    import imp
    if imp.get_suffixes()[0][0] == '_d.pyd':
        clibname += 'd'

    standard_c_lib = ctypes.cdll.LoadLibrary(clibname+'.dll')

This code works on all pythons I have on my machine: official builds,
custom builds (relase/debug) with several MS compilers...
I did not test it with other compiled vendors (mingw32...).

But to me this seems more robust than a text search in the executable.
msg60007 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2008-01-16 20:50
Amaury Forgeot d'Arc schrieb:
> This code works on all pythons I have on my machine: official builds,
> custom builds (relase/debug) with several MS compilers...
> I did not test it with other compiled vendors (mingw32...).

What I do not like about your code is that it imports distutils.
On the other hand, the code in distutils.msvccompiler.get_build_version
is so small and simple that it could easily be duplicated in ctypes.util;
it could even be simplified more because ctypes doesn't work in Python < 2.3.

What do you think?
msg60023 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-01-17 11:13
Fine with me.
msg66966 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2008-05-16 20:13
Committed in trunk as rev. 63395.  I've changed the code that Amaury
suggested so that None is returned when get_build_version() returns
None.  Thanks.
Date User Action Args
2008-05-16 20:13:58thellersetstatus: open -> closed
resolution: fixed
messages: + msg66966
2008-01-17 11:13:21amaury.forgeotdarcsetmessages: + msg60023
2008-01-16 20:50:57thellersetmessages: + msg60007
2008-01-15 12:42:04amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg59963
2008-01-11 18:27:01thellersetmessages: + msg59732
2008-01-11 17:41:20christian.heimessetnosy: + christian.heimes
messages: + msg59728
2008-01-11 14:59:37thellercreate