Python Embedding with IPython: WindowsError: [Erro

2019-07-06 10:34发布

问题:

Trying to run:

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("import IPython\n"
                     "IPython.embed()\n");
  Py_Finalize();
  return 0;
}

compiled with mignw64 gcc 4.6.0 ( g++ -I /c/prog64/Python27/include t.cpp /c/prog64/Python27/libs/libpython27.a ) under Windwos 7 I get the error:

$ a.exe
Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "c:\prog64\python27\lib\site-packages\IPython\terminal\embed.py", line 290, in embed
    shell = InteractiveShellEmbed.instance(**kwargs)
  File "c:\prog64\python27\lib\site-packages\IPython\config\configurable.py", line 354, in instance
    inst = cls(*args, **kwargs)
  File "c:\prog64\python27\lib\site-packages\IPython\terminal\embed.py", line 92, in __init__
    display_banner=display_banner
  File "c:\prog64\python27\lib\site-packages\IPython\terminal\interactiveshell.py", line 328, in  __init__
    **kwargs
  File "c:\prog64\python27\lib\site-packages\IPython\core\interactiveshell.py", line 483, in __init__
    self.init_readline()
  File "c:\prog64\python27\lib\site-packages\IPython\core\interactiveshell.py", line 1817, in init_readline
    import IPython.utils.rlineimpl as readline
  File "c:\prog64\python27\lib\site-packages\IPython\utils\rlineimpl.py", line 21, in <module>
    _rl = __import__(_rlmod_name)
  File "c:\prog64\python27\lib\site-packages\readline.py", line 6, in <module>
    from pyreadline.rlmain import Readline
  File "c:\prog64\python27\lib\site-packages\pyreadline\__init__.py", line 11, in <module>
    from . import unicode_helper, logger, clipboard, lineeditor, modes, console
  File "c:\prog64\python27\lib\site-packages\pyreadline\console\__init__.py", line 15, in <module>
    from .console import *
  File "c:\prog64\python27\lib\site-packages\pyreadline\console\console.py", line 610, in <module>
    msvcrt = cdll.LoadLibrary(ctypes.util.find_msvcrt())
  File "C:\prog64\Python27\Lib\ctypes\__init__.py", line 443, in LoadLibrary
    return self._dlltype(name)
  File "C:\prog64\Python27\Lib\ctypes\__init__.py", line 365, in __init__
    self._handle = _dlopen(self._name, mode)
WindowsError: [Error 193] %1 is not a valid Win32 applicationTraceback (most recent call last):

Note that other commands in the PyRun_SimpleString do work; also, in a command line python session:

import IPython
IPython.embed()

works.

I expect the problem is related to MSVCR90.DLL where the _dlopen looks for, and the fact that g++ links to the "normal" MSVCRT.DLL. Compiling with VS2008 is no easy option. Same error message is seen when compiling with VS2010. Python setup is Anaconda Python 2.7.8 64 bit.

回答1:

Problem indeed is related to msvcr90.dll. Way to solve it is to link the program against msvcr90.dll. However, to link against msvcr90.dll you need to have a manifest or you will get a runtime error. This manifest looks like:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

which I extracted from python.exe with a text editor and named msvcr90.manifest. This manifest is linked into the application using the resource file msvcr90.rc

#include "winuser.h"
1 RT_MANIFEST msvcr90.manifest

which in turned can be compiled into an object file using:

windres msvcr90.rc msvcr90.o

Than, compilation of the program with this resource file and msvcr90.dll becomes:

g++ -I /c/prog64/Python27/include t.cpp /c/prog64/Python27/libs/libpython27.a msvcr90.o msvcr90.dll

where I copied msvcr90.dll from c:/Windows/winsxs/amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_none_750b37ff97f4f68b/msvcr90.dll

Input for this came from

  • https://cournape.wordpress.com/2008/09/02/how-to-embed-a-manifest-into-a-dll-with-mingw-tools-only
  • Manifest being ignored in mingw app
  • http://www.mingw.org/wiki/MS_resource_compiler
  • https://lists.launchpad.net/kicad-developers/msg09473.html

and a couple of other web pages which explained me how to do this.