1

我在 windows 7/64、matlab 2015a 上使用 winpython (2.7) 和 matlab 的新python 桥

>> py.ctypes.util.find_library('c')

ans = 

  Python str with no properties.

    msvcr90.dll

>> py.ctypes.util.find_msvcrt()

ans = 

  Python str with no properties.

    msvcr90.dll

>> py.ctypes.CDLL(py.ctypes.util.find_library('c'))
Python Error: [Error 1114] A dynamic link library (DLL) initialization routine failed

>> x=CDLL('C:\Users\nlab\Downloads\WinPython-64bit-2.7.9.5\python-2.7.9.amd64\msvcr90.dll')
Python Error: [Error 1114] A dynamic link library (DLL) initialization routine failed

还会出现一个弹出窗口:

Microsoft Visual C++ Runtime Library
R6034 "an application has made an attempt to load the c runtime library incorrectly"

其他几个 SO 答案表明它是 matlab 将其不兼容的 msvc*.dll 副本放在路径上的某个位置,所以我删除了 sys.path 中不是来自 WinPython 的所有内容(只是 matlab\bin\win64\\Python27\site-packages\我拥有的另一个 python 安装):

>> py.pprint.PrettyPrinter().pprint(py.sys.path)
['',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\python27.zip',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\DLLs',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\plat-win',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\lib-tk',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\site-packages',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\site-packages\\FontTools',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\site-packages\\win32',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\site-packages\\win32\\lib',
 'C:\\Users\\nlab\\Downloads\\WinPython-64bit-2.7.9.5\\python-2.7.9.amd64\\lib\\site-packages\\Pythonwin']

仍然有大量的 msvc*.dll 散布在系统上,而且肯定有一些在 PATH 上:

>> x = py.os.environ

x = 

  Python _Environ with properties:

    data: [1x1 py.dict]

    {'TMP': 'C:\\Users\\nlab\\AppData\\Local\\Temp', <<snip>>, 'USERPROFILE': 'C:\\Users\\nlab'}

>> cellfun(@(s)fprintf('%s\n',s),strsplit(char(x{'PATH'}),';'))
C:\Program Files\Haskell\bin
C:\Program Files\Haskell Platform\2014.2.0.0\lib\extralibs\bin
C:\Program Files\Haskell Platform\2014.2.0.0\bin
C:\Users\nlab\Downloads\WinPython-64bit-2.7.9.5\python-2.7.9.amd64
C:\Users\nlab\Downloads\opencv\build\x64\vc12\bin
C:\ProgramData\Oracle\Java\javapath
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\bin\
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\libnvvp\
C:\Program Files\ImageMagick-6.8.3-Q16
C:\Program Files (x86)\OSSBuild\GStreamer\v0.10.7\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\libnvvp\
C:\Program Files (x86)\PHP\
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Program Files\Intel\DMIX
C:\Program Files\TortoiseSVN\bin
C:\Program Files\SlikSvn\bin\
C:\Program Files\MySQL\MySQL Server 5.5\bin
C:\Program Files (x86)\Common Files\Acronis\SnapAPI\
C:\Program Files (x86)\PostgreSQL\9.2\bin
C:\Python27
C:\Python27\Scripts
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\
C:\Windows\System32\WindowsPowerShell\v1.0\
C:\Program Files (x86)\LilyPond\usr\bin
C:\Program Files (x86)\Git\cmd
C:\Program Files\Microsoft Windows Performance Toolkit\
C:\Program Files\TortoiseGit\bin
C:\Program Files (x86)\QuickTime\QTSystem\
C:\Program Files (x86)\Skype\Phone\
C:\Program Files\Mosek\7\tools\platform\win64x86\bin
C:\Program Files\Haskell Platform\2014.2.0.0\mingw\bin
C:\Users\nlab\AppData\Roaming\cabal\bin
C:\Program Files (x86)\SSH Communications Security\SSH Secure Shell
C:\Gtk+\bin

我注意到C:\Program Files\MATLAB\R2015a\bin\win64\我们只有msvc[r|p][100|110].dll- 这是否意味着它不适用于基于 msvcr90 的 python 发行版,如 winpython 2.7.9.5?

4

2 回答 2

0

将此定义为文件msvc.py

import ctypes
print ctypes.cdll.msvcrt

然后在matlab中:

>> py.importlib.import_module('msvc')
<CDLL 'msvcrt', handle fe190000 at 771c2b38>

ans = 

  Python module with properties:

    ctypes: [1x1 py.module]

    <module 'msvc' from 'msvc.pyc'>

>> x = py.ctypes.cdll

x = 

  Python LibraryLoader with properties:

    msvcrt: [1x1 py.ctypes.CDLL]

    <ctypes.LibraryLoader object at 0x00000000771D6278>

>> x.msvcrt

ans = 

  Python CDLL with no properties.

    <CDLL 'msvcrt', handle fe190000 at 771c2b38>

我不知道为什么有必要使用msvc.py- 只是导入ctypes不会给你一个cdll属性msvcrt

于 2015-06-11T10:17:09.843 回答
0

@eryksun 的方法有效。

问题仍然存在,为什么要以它们的方式执行ctypes.cdll.msvcrtfind_library('c')他们应该只使用@eryksun 的方法来返回python 清单中的dll,对吗?

from ctypes import *
from ctypes.wintypes import *

kernel32 = WinDLL("kernel32")

ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x001
ACTCTX_FLAG_LANGID_VALID = 0x002
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004
ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008
ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x010
ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x020
ACTCTX_FLAG_HMODULE_VALID = 0x080
DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION = 1

INVALID_HANDLE_VALUE = HANDLE(-1).value
ULONG_PTR = WPARAM  # pointer-sized unsigned integer

class ACTCTX(Structure):
    _fields_ = (("cbSize", ULONG),
                ("dwFlags", DWORD),
                ("lpSource", LPCWSTR),
                ("wProcessorArchitecture", USHORT),
                ("wLangId", LANGID),
                ("lpAssemblyDirectory", LPCWSTR),
                ("lpResourceName", LPCWSTR),
                ("lpApplicationName", LPCWSTR),
                ("hModule", HMODULE))

    def __init__(self, *args, **kwds):
        super(ACTCTX, self).__init__(sizeof(self), *args, **kwds)

CreateActCtxW = kernel32.CreateActCtxW
CreateActCtxW.restype = HANDLE
CreateActCtxW.argtypes = (POINTER(ACTCTX),)
ReleaseActCtx = kernel32.ReleaseActCtx
ReleaseActCtx.restype = None
ReleaseActCtx.argtypes = (HANDLE,)
ActivateActCtx = kernel32.ActivateActCtx
ActivateActCtx.argtypes = (HANDLE, POINTER(ULONG_PTR))
DeactivateActCtx = kernel32.DeactivateActCtx
DeactivateActCtx.argtypes = (DWORD, ULONG_PTR)

def getMsvcr90():
    ctx = ACTCTX(hModule = cdll.python27._handle 
                ,lpResourceName = c_wchar_p(2)
                ,dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID
                )
    hActCtx = CreateActCtxW(byref(ctx))
    if hActCtx == INVALID_HANDLE_VALUE:
        raise WinError()

    cookie = ULONG_PTR()
    if not ActivateActCtx(hActCtx, byref(cookie)):
        raise WinError()
    msvcr90 = CDLL("msvcr90")
    if not DeactivateActCtx(0, cookie):
        raise WinError()

    ReleaseActCtx(hActCtx)

    # show DLL path
    hModule = HANDLE(msvcr90._handle)
    path = (c_wchar * 260)()    
    kernel32.GetModuleFileNameW(hModule, path, len(path))
    print(path.value)

    return msvcr90
于 2015-06-13T00:49:28.593 回答