简体   繁体   English

调试Python的C ++扩展

[英]Debugging C++ extension for Python

I have a problem when I try to debug my C++ extension for Python. 尝试调试Python的C ++扩展时遇到问题。 The error is 错误是
Fatal Python error: PyThreadState_Get: no current thread 致命的Python错误:PyThreadState_Get:当前没有线程

I followed this guide and it works when I run in the release version. 我遵循了本指南,并且在发行版中运行时可以使用。

Python code: Python代码:

from itertools import islice
from random import random
from time import perf_counter

COUNT = 500000  # Change this value depending on the speed of your computer
DATA = list(islice(iter(lambda: (random() - 0.5) * 3.0, None), COUNT))

e = 2.7182818284590452353602874713527

def sinh(x):
    return (1 - (e ** (-2 * x))) / (2 * (e ** -x))

def cosh(x):
    return (1 + (e ** (-2 * x))) / (2 * (e ** -x))

def tanh(x):
    tanh_x = sinh(x) / cosh(x)
    return tanh_x

def sequence_tanh(data):
    '''Applies the hyperbolic tangent function to map all values in
    the sequence to a value between -1.0 and 1.0.
    '''
    result = []
    for x in data:
        result.append(tanh(x))
    return result

def test(fn, name):
    start = perf_counter()
    result = fn(DATA)
    duration = perf_counter() - start
    print('{} took {:.3f} seconds\n\n'.format(name, duration))

    for d in result:
        assert -1 <= d <=1, " incorrect values"

from superfastcode import fast_tanh
if __name__ == "__main__":
   test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d]')

C++ code: C ++代码:

#include <Python.h>
#include <cmath>

const double e = 2.7182818284590452353602874713527;

double sinh_impl(double x) {
    return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
}

double cosh_impl(double x) {
    return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
}

PyObject* tanh_impl(PyObject *, PyObject* o) {
    double x = PyFloat_AsDouble(o);
    double tanh_x = sinh_impl(x) / cosh_impl(x);
    return PyFloat_FromDouble(tanh_x);
}

static PyMethodDef superfastcode_methods[] = {
    // The first property is the name exposed to Python, fast_tanh, the second is the C++
    // function name that contains the implementation.
    { "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },

    // Terminate the array with an object containing nulls.
{ nullptr, nullptr, 0, nullptr }
};

static PyModuleDef superfastcode_module = {
    PyModuleDef_HEAD_INIT,
    "superfastcode",                        // Module name to use with Python import statements
    "Provides some functions, but faster",  // Module description
    0,
    superfastcode_methods                   // Structure that defines the methods of the module
};

PyMODINIT_FUNC PyInit_superfastcode() {
    return PyModule_Create(&superfastcode_module);
}

I am using the 64 bit version of Python 3.6, and are building the C++ code in x64 mode. 我正在使用Python 3.6的64位版本,并正在x64模式下构建C ++代码。 Visual Studio 2017 15.6.4 Visual Studio 2017 15.6.4

I am linking with C:\\Python\\Python36.x64\\libs\\python36_d.lib and including header files from C:\\Python\\Python36.x64\\include 我正在链接C:\\ Python \\ Python36.x64 \\ libs \\ python36_d.lib并包含C:\\ Python \\ Python36.x64 \\ include中的头文件
My Python interpreter is in C:\\Python\\Python36.x64\\ 我的Python解释器位于C:\\ Python \\ Python36.x64 \\

I get this result when I run the release build 运行发布版本时得到此结果

[fast_tanh(x) for x in d] took 0.067 seconds

Update : I got it running in Py x86 but not x64. 更新 :我让它在Py x86而不是x64上运行。 When I hit the break point and step over (F10) it throws an exception. 当我到达断点并越过(F10)时,它将引发异常。

在此处输入图片说明 在此处输入图片说明

I got this solution from Steve Dower @ Microsoft: 我从Microsoft的Steve Dower获得了此解决方案:
This looks more like a mismatch between debug binaries and release headers. 这看起来更像是调试二进制文件和发行标头之间的不匹配。

The guide you've referenced is designed to always use the release binaries of Python, even if you are building a debug extension. 您参考的指南旨在始终使用Python的发行版二进制文件,即使您正在构建调试扩展。 So either you should be linking against python36.lib/python36.dll, or ignoring most of the setting changes listed in the guide and linking against python36_d.lib/python36_d.dll (the linking should be automatic once you set the paths - the choice of C runtime library will determine whether debug/release Python is used). 因此,要么应该链接到python36.lib / python36.dll,要么忽略指南中列出的大多数设置更改,然后链接到python36_d.lib / python36_d.dll(一旦设置了路径,链接应该是自动的-选择C运行时库的确定将确定是否使用调试/发布Python)。

Reference: PTVS issues 参考: PTVS问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM