Python용 C++ 확장 만들기Creating a C++ extension for Python

C++(또는 C)로 작성된 모듈은 하위 수준 운영 체제 기능에 대한 액세스를 가능하게 할 뿐만 아니라 Python 인터프리터의 기능을 확장하는 데 일반적으로 사용됩니다.Modules written in C++ (or C) are commonly used to extend the capabilities of a Python interpreter as well as to enable access to low-level operating system capabilities. 모듈은 세 가지 기본 형식이 있습니다.There are three primary types of modules:

  • 액셀러레이터 모듈: Python은 해석된 언어이기 때문에 성능 향상을 위해 특정 코드 부분을 C++로 작성할 수 있습니다.Accelerator modules: because Python is an interpreted language, certain pieces of code can be written in C++ for higher performance.
  • 래퍼 모듈: 래퍼는 기존 C/C++ 인터페이스를 Python 코드에 노출하거나 Python에서 사용하기 쉬운 보다 “Python” 최적화된 API를 노출합니다.Wrapper modules: wrappers expose existing C/C++ interfaces to Python code or expose a more "Pythonic" API that's easy to use from Python.
  • 하위 수준 시스템 액세스 모듈: CPython 런타임, 운영 체제 또는 기본 하드웨어의 하위 수준 기능에 액세스하기 위해 만들었습니다.Low-level system access modules: created to access lower-level features of the CPython runtime, the operating system, or the underlying hardware.

이 항목에서는 쌍곡 탄젠트를 계산하고 Python 코드에서 호출하는 CPython용 C++ 확장을 빌드하는 방법에 대해 설명합니다.This topic walks through building a C++ extension module for CPython that computes a hyperbolic tangent and calls it from Python code. C++에서 동일한 루틴을 구현할 경우의 성능 향상을 보여 주기 위해 Python에서 먼저 루틴을 구현합니다.The routine is implemented first in Python to demonstrate the performance gain of implementing the same routine in C++.

여기에서 사용된 방법은 Python 설명서에 설명된 대로 표준 CPython 확장용입니다.The approach taken here is that for standard CPython extensions as described in the Python documentation. 이 방법과 다른 방법의 비교는 이 항목의 끝에 있는 대체 방법에 설명되어 있습니다.A comparison between this and other means is described under alternative approaches at the end of this topic.

필수 구성 요소Prerequisites

  • 기본 옵션과 함께 설치된 C++를 사용한 데스크톱 개발Python 개발 워크로드를 모두 사용하는 Visual Studio 2017.Visual Studio 2017 with both the Desktop Development with C++ and Python Development workloads installed with default options.
  • Python 개발 워크로드에서는 Python 네이티브 개발 도구의 오른쪽에 있는 확인란을 선택합니다. 그러면 이 항목에 설명된 대부분의 옵션이 설정됩니다.In the Python Development workload, also check the box on the right for Python native development tools, which sets up most of the options described in this topic. 이 옵션에는 C++ 워크로드도 자동으로 포함됩니다.(This option also includes the C++ workload automatically.)

Python 네이티브 개발 도구 옵션 선택

  • 데이터 과학 및 분석 응용 프로그램 워크로드 설치에는 Python 및 Python 네이티브 개발 도구 옵션이 기본적으로 포함됩니다.Installing the Data science and analytical applications workload also includes Python and the Python native development tools option by default.

다른 버전의 Visual Studio 사용을 포함한 자세한 내용은 Visual Studio용 Python 지원 설치를 참조하세요.For more information, see Installing Python Support for Visual Studio, including using other versions of Visual Studio. Python을 별도로 설치하는 경우 설치 관리자의 고급 옵션에서 디버깅 기호 다운로드디버그 버전의 이진 파일 다운로드를 선택해야 합니다.If you install Python separately, be sure to select Download debugging symbols and Download debug binaries under Advanced Options in the installer. 이 옵션은 디버그 빌드를 수행하도록 선택할 경우 필요한 디버그 라이브러리를 사용할 수 있도록 합니다.This option ensures that you have the necessary debug libraries available if you choose to do a debug build.

Python 응용 프로그램 만들기Create the Python application

  1. 파일 > 새로 만들기 > 프로젝트를 선택하여 Visual Studio에서 새 Python 프로젝트를 만듭니다.Create a new Python project in Visual Studio by selecting File > New > Project. “Python”을 검색하고 Python 응용 프로그램 템플릿을 선택한 다음 적합한 이름과 위치를 지정하고 확인을 선택합니다.Search for "Python", select the Python Application template, give it a suitable name and location, and select OK.

  2. 프로젝트의 .py 파일에서 쌍곡 탄젠트 계산(더 쉬운 비교를 위해 수학 라이브러리를 사용하지 않고 구현됨)을 벤치마크하는 다음 코드를 붙여넣습니다.In the project's .py file, paste the following code that benchmarks the computation of a hyperbolic tangent (implemented without using the math library for easier comparison). 언제든지 코드를 수동으로 입력하여 Python 편집 기능의 일부를 경험해 보세요.Feel free to enter the code manually to experience some of the Python editing features.

    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"
    
    if __name__ == "__main__":
        print('Running benchmarks with COUNT = {}'.format(COUNT))
        test(sequence_tanh, 'sequence_tanh')
    
        test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d]')
    
  3. 디버그 > 디버깅하지 않고 시작(Ctrl+F5)을 사용하여 프로그램을 실행하고 결과를 확인합니다.Run the program using Debug > Start without Debugging (Ctrl+F5) to see the results. COUNT 변수를 조정하여 벤치 마크를 실행할 시간을 변경할 수 있습니다.You can adjust the COUNT variable to change how long the benchmarks take to run. 이 연습의 목적을 위해 벤치마크마다 약 2초가 걸리도록 수를 설정합니다.For the purposes of this walkthrough, set the count so that each benchmark takes around two seconds.

핵심 C++ 프로젝트 만들기Create the core C++ project

  1. 솔루션 탐색기에서 솔루션을 마우스 오른쪽 단추로 클릭하고 추가 > 새 프로젝트...를 선택합니다. Visual Studio 솔루션에는 Python 및 C++ 프로젝트가 함께 포함될 수 있습니다.Right-click the solution in Solution Explorer and select Add > New Project.... A Visual Studio solution can contain both Python and C++ projects together.

  2. “C++”를 검색하고, 빈 프로젝트를 선택하고, 이름(예: TanhBenchmark)을 지정한 다음 확인을 선택합니다.Search on "C++", select Empty project, specify a name (such as TanhBenchmark), and select OK. 참고: Visual Studio 2017과 함께 Python 네이티브 개발 도구를 설치한 경우 여기에 설명된 내용이 이미 많이 포함되어 있는 Python 확장 모듈 템플릿으로 시작할 수 있습니다.Note: if you've installed the Python native development tools with Visual Studio 2017, you can start with the Python Extension Module template, which has much of what's described here already in place. 그러나 이 연습에서는 빈 프로젝트로 시작하여 확장 모듈 빌드를 단계별로 보여 줍니다.For this walkthrough, though, starting with an empty project demonstrates building the extension module step by step.

  3. 새 프로젝트에서 소스 파일 노드를 마우스 오른쪽 단추로 클릭하여 C++ 파일을 만들고, 추가 > 새 항목..."을 선택하고 C++ 파일을 선택하여 이름(예: module.cpp)을 지정한 다음 확인을 선택합니다.Create a C++ file in the new project by right-clicking the Source Files node, then select Add > New Item...", select C++ File, give it a name (like module.cpp), and select OK. 이 단계는 다음 단계에서 C++ 속성 페이지를 설정하는 데 필요합니다.This step is necessary to turn on the C++ property pages in the next steps.

  4. 새 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 표시되는 속성 페이지 대화 상자 맨 위에서 구성모든 구성으로 설정합니다.Right-click the new project and select Properties, then at the top of the Property Pages dialog that appears, set Configuration to All Configurations.

  5. 아래에 설명된 대로 특정 속성을 설정한 다음, 확인을 선택합니다.Set the specific properties as described below, then select OK.

    Tab 속성Property Value
    일반General 일반 > 대상 이름General > Target Name Python에 표시되는 모듈의 이름과 정확하게 일치하도록 이 필드를 설정합니다.Set this field to exactly match the name of the module as Python sees it.
    일반 > 대상 확장명General > Target Extension .pyd.pyd
    프로젝트 기본값 > 구성 형식Project Defaults > Configuration Type 동적 라이브러리(.dll)Dynamic Library (.dll)
    C/C++ > 일반C/C++ > General 추가 포함 디렉터리Additional Include Directories 설치에 맞게 Python include 폴더를 추가합니다(예: c:\Python36\include).Add the Python include folder as appropriate for your installation, for example, c:\Python36\include
    C/C++ > 전처리기C/C++ > Preprocessor 전처리기 정의Preprocessor Definitions 문자열의 시작 부분에 Py_LIMITED_API;를 추가합니다. 그러면 Python에서 호출할 수 있는 일부 함수가 제한되고 다른 버전의 Python 간 코드 이식성이 향상됩니다.Add Py_LIMITED_API; to the beginning of the string, which restricts some of the functions you can call from Python and makes the code more portable between different versions of Python.
    C/C++ > 코드 생성C/C++ > Code Generation 런타임 라이브러리Runtime Library 다중 스레드 DLL(/ MD)(아래 경고 참조)Multi-threaded DLL (/MD) (see Warning below)
    링커 > 일반Linker > General 추가 라이브러리 디렉터리Additional Library Directories .lib 파일을 포함하는 Python libs 폴더를 설치에 맞게 추가합니다(예: c:\Python36\libs).Add the Python libs folder containing .lib files as appropriate for your installation, for example, c:\Python36\libs. .py 파일을 포함하는 Lib 폴더가 아니라 .lib 파일을 포함하는 libs 폴더를 가리켜야 합니다.(Be sure to point to the libs folder that contains .lib files, and not the Lib folder that contains .py files.)

    C/C++ 탭이 표시되지 않는 경우 프로젝트에 C/C++ 소스 파일로 식별되는 파일이 포함되어 있지 않기 때문입니다.If you don't see the C/C++ tab, it's because the project doesn't contain any files that it identifies as C/C++ source files. .c 또는 .cpp 확장명을 사용하지 않고 소스 파일을 만드는 경우 이런 상태가 발생할 수 있습니다.This condition can occur if you create a source file without a .c or .cpp extension. 예를 들어 이전의 새 항목 대화 상자에서 실수로 module.cpp 대신 module.coo를 입력한 경우 Visual Studio에서 파일을 만들지만, C/C++ 속성 탭을 활성화하는 “C/C++ 코드”로 파일 형식을 설정하지 않습니다. 파일 이름을 .cpp로 변경하는 경우에도 여전히 잘못 식별됩니다.For example, if you accidentally entered module.coo instead of module.cpp in the new item dialog earlier, then Visual Studio creates the file but doesn't set the file type to "C/C+ Code," which is what activates the C/C++ properties tab. This misidentification remains the case even if you rename the file with .cpp. 파일 형식을 제대로 설정하려면 솔루션 탐색기에서 파일을 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 파일 형식C/C++ 코드로 설정합니다.To set the file type properly, right-click the file in Solution Explorer, select Properties, then set File Type to C/C++ Code.

    경고

    디버그 구성의 경우에도 C/C++ > 코드 생성 > 런타임 라이브러리 옵션을 “다중 스레드 디버그 DLL(/MDd)”로 설정하지 마세요.Don't set the C/C++ > Code Generation > Runtime Library option to "Multi-threaded Debug DLL (/MDd)" even for a Debug configuration. 디버그가 아닌 Python 이진 파일 작성에 사용되기 때문에 “다중 스레드 DLL(/MD)” 런타임을 선택합니다.Select the "Multi-threaded DLL (/MD)" runtime because that's what the non-debug Python binaries are built with. /MDd 옵션을 설정한 경우 DLL의 디버그 구성을 빌드하면 C1189: Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG(C1189: Py_LIMITED_API가 Py_DEBUG, Py_TRACE_REFS 및 Py_REF_DEBUG와 호환되지 않음) 오류가 표시됩니다.If you happen to set the /MDd option, you see error C1189: Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG when building a Debug configuration of your DLL. 또한 빌드 오류를 방지하기 위해 Py_LIMITED_API를 제거하는 경우 모듈을 가져오려고 하면 Python이 충돌합니다.Furthermore, if you remove Py_LIMITED_API to avoid the build error, Python crashes when attempting to import the module. 뒷부분에 설명된 대로 충돌은 DLL의 PyModule_Create 호출 내에서 발생하고 Fatal Python error: PyThreadState_Get: no current thread(Python 오류: PyThreadState_Get: 현재 스레드 없음)라는 메시지가 출력됩니다.(The crash happens within the DLL's call to PyModule_Create as described later, with the output message of Fatal Python error: PyThreadState_Get: no current thread.)

    /MDd 옵션은 Python 디버그 이진 파일(예: python_d.exe)을 빌드하는 데 사용되지만 확장 DLL용으로 선택하면 Py_LIMITED_API에서 빌드 오류가 발생합니다.Note that the /MDd option is what's used to build the Python debug binaries (such as python_d.exe), but selecting it for an extension DLL still causes the build error with Py_LIMITED_API.

  6. C++ 프로젝트를 마우스 오른쪽 단추로 클릭하고 빌드를 선택하여 구성(디버그 및 릴리스)을 테스트합니다.Right-click the C++ project and select Build to test your configurations (both Debug and Release). .pyd 파일은 C++ 프로젝트 폴더 자체가 아니라 디버그릴리스 아래의 솔루션 폴더에 있습니다.The .pyd files are located in the solution folder under Debug and Release, not the C++ project folder itself.

  7. C++ 프로젝트의 주 .cpp 파일에 다음 코드를 추가합니다.Add the following code to the C++ project's main .cpp file:

    #include <Windows.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));
    }
    
    double tanh_impl(double x) {
        return sinh_impl(x) / cosh_impl(x);
    }
    
  8. C++ 프로젝트를 다시 빌드하여 코드가 올바른지 확인합니다.Build the C++ project again to confirm that your code is correct.

C++ 프로젝트를 Python용 확장으로 변환Convert the C++ project to an extension for Python

C++ DLL을 Python용 확장으로 만들려면 내보낸 메서드를 Python 형식과 상호 작용하도록 수정해야 합니다.To make the C++ DLL into an extension for Python, you need to modify the exported methods to interact with Python types. 그런 다음 모듈의 메서드 정의와 함께 모듈을 내보내는 함수를 추가해야 합니다.Then you need to add a function that exports the module, along with definitions of the module's methods. 여기에 설명된 내용에 대한 배경 정보는 python.org에서 Python/C API Reference Manual(Python/C API 참조 설명서) 및 특히 Module Objects(모듈 개체)를 참조하세요. 오른쪽 위 드롭다운 컨트롤에서 Python의 버전을 선택해야 합니다.For background on what's shown here, refer to the Python/C API Reference Manual and especially Module Objects on python.org. (Remember to select your version of Python from the drop-down control on the upper right.)

  1. C++ 파일의 맨 위에 Python.h를 포함합니다.In the C++ file, include Python.h at the top:

    #include <Python.h>
    
  2. Python 형식을 허용하고 반환하도록 tanh_impl 메서드를 수정합니다.Modify the tanh_impl method to accept and return Python types:

    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);
    }
    
  3. C++ tanh 함수가 Python에 표시되는 방식을 정의하는 구조체를 추가합니다.Add a structure that defines how the C++ tanh function is presented to Python:

    static PyMethodDef superfastcode_methods[] = {
        // The first property is the name exposed to python, the second is the C++ function name        
        { "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },
    
        // Terminate the array with an object containing nulls.
        { nullptr, nullptr, 0, nullptr }
    };
    
  4. Python 코드를 통해 표시된 대로 모듈을 정의하는 구조체를 추가합니다.Add a structure that defines the module as you see it through Python code. (module.cpp와 같은 C++ 프로젝트 내부의 파일 이름은 중요하지 않습니다.)(Filenames internal to the C++ project, like module.cpp, are inconsequential.)

    static PyModuleDef superfastcode_module = {
        PyModuleDef_HEAD_INIT,
        "superfastcode",                        // Module name as Python sees it
        "Provides some functions, but faster",  // Module description
        0,
        superfastcode_methods                   // Structure that defines the methods
    };
    
  5. Python에서 이름이 PyInit_<module-name>인 모듈을 로드할 때 호출하는 메서드를 추가합니다. 여기서 <module_name>은 C++ 프로젝트의 일반 > 대상 이름 속성과 정확하게 일치합니다. 즉, 프로젝트에서 빌드된 .pyd의 파일 이름과 일치합니다.Add a method that Python calls when it loads the module, which must be named PyInit_<module-name>, where <module_name> exactly matches the C++ Project's General > Target Name property (that is, it matches the filename of the .pyd built by the project).

    PyMODINIT_FUNC PyInit_superfastcode() {    
        return PyModule_Create(&superfastcode_module);
    }
    
  6. C++ 프로젝트를 다시 빌드하여 코드를 확인합니다.Build the C++ project again to verify your code.

코드를 테스트하고 결과 비교Test the code and compare the results

DLL을 Python 확장으로 구조화했으므로 Python 프로젝트에서 참조하고, 모듈을 가져오며 해당 메서드를 사용할 수 있습니다.Now that you have the DLL structured as a Python extension, you can refer to it from the Python project, import the module, and use its methods.

Python에서 DLL을 사용할 수 있도록 설정Make the DLL available to Python

Python에서 DLL을 사용할 수 있도록 설정하는 방법은 두 가지가 있습니다.There are two ways to make the DLL available to Python.

첫째, 두 프로젝트가 동일한 Visual Studio 솔루션에 있는 경우 Python 프로젝트에서 참조를 C++ 프로젝트에 추가할 수 있습니다.First, you can add a reference from the Python project to the C++ project, provided that they're in the same Visual Studio solution:

  1. 솔루션 탐색기의 Python 프로젝트에서 참조 노드를 마우스 오른쪽 단추로 클릭하고 참조 추가를 선택합니다.In Solution Explorer, right-click the References node in your Python project and select Add Reference. 나타나는 대화 상자에서 프로젝트 탭을 선택하고 superfastcode 프로젝트(또는 사용 중인 이름)를 선택한 다음 확인을 선택합니다.In the dialog that appears, select the Projects tab, select the superfastcode project (or whatever name you're using), and then OK.

둘째, 모듈을 글로벌 Python 환경에 설치하여 다른 Python 프로젝트에서도 사용 가능하도록 할 수 있습니다.Second, you can install the module in the global Python environment, making it available to other Python projects as well. 이 경우 일반적으로 해당 환경에 대한 IntelliSense 완성 데이터베이스를 새로 고쳐야 합니다.Doing so typically requires that you refresh the IntelliSense completion database for that environment. 환경에서 모듈을 제거하는 경우에도 새로 고침이 필요합니다.Refreshing is also necessary when removing the module from the environment.

  1. Visual Studio 2017을 사용하고 있는 경우 Visual Studio 설치 관리자를 실행하고 수정을 선택한 다음 개별 구성 요소 > 컴파일러, 빌드 도구 및 런타임 > Visual C++ 2015.3 v140 toolset(Visual C++ 2015.3 v140 도구 집합)를 선택합니다.If you're using Visual Studio 2017, run the Visual Studio installer, select Modify, select Individual Components > Compilers, build tools, and runtimes > Visual C++ 2015.3 v140 toolset. 이 단계가 필요한 이유는 Python(Windows용) 자체는 Visual Studio 2015(버전 14.0)로 빌드되며 여기에 설명된 메서드를 통해 확장을 빌드할 경우 이러한 도구를 사용할 수 있다고 예상하기 때문입니다.This step is necessary because Python (for Windows) is itself built with Visual Studio 2015 (version 14.0) and expects that those tools are available when building an extension through the method described here.

  2. 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가 > 새 항목...을 선택하여 C++ 프로젝트에서 setup.py라는 파일을 만듭니다. 그런 다음 “C++ 파일(.cpp)”을 선택하고 파일 이름을 setup.py로 변경하고 확인을 선택합니다(파일 이름을 .py 확장으로 변경하면 Visual Studio에서 C++ 파일 템플릿을 사용함에도 불구하고 Python으로 인식함).Create a file named setup.py in your C++ project by right-clicking the project and selecting Add > New Item.... Then select "C++ File (.cpp)", name the file setup.py, and selecting OK (naming the file with the .py extension makes Visual Studio recognize it as Python despite using the C++ file template). 편집기에 파일이 표시되면 다음 코드를 붙여넣습니다.When the file appears in the editor, paste the following code into it:

    from distutils.core import setup, Extension, DEBUG
    
    sfc_module = Extension('superfastcode', sources = ['module.cpp'])
    
    setup(name = 'superfastcode', version = '1.0',
        description = 'Python Package with superfastcode C++ Extension',
        ext_modules = [sfc_module]
        )
    

    이 스크립트에 대한 설명서는 Building C and C++ Extensions(C 및 C++ 확장 빌드)(python.org)를 참조하세요.See Building C and C++ Extensions (python.org) for documentation on this script.

  3. setup.py 코드는 명령줄에서 사용되는 경우 Visual Studio 2015 C++ 도구 집합을 사용하여 확장을 빌드하도록 Python에 지시합니다.The setup.py code instructs Python to build the extension using the Visual Studio 2015 C++ toolset when used from the command line. 관리자 권한 명령 프롬프트를 열고 C++ 프로젝트 및 setup.py를 포함하는 폴더로 이동한 후 다음 명령을 입력합니다.Open an elevated command prompt, navigate to the folder containing the C++ project (and setup.py), and enter the following command:

    pip install .
    

Python에서 DLL 호출Call the DLL from Python

위의 방법 중 하나를 완료하면 이제 fast_tanh 함수를 호출하고, 해당 성능을 Python 구현과 비교할 수 있습니다.After you've completed either of the methods above, you can now call the fast_tanh function and compare its performance to the Python implementation:

  1. .py 파일에서 다음 줄을 추가하여 DLL에서 가져온 fast_tanh 메서드를 호출하고 출력을 표시합니다.Add the following lines in your .py file to call the fast_tanh method exported from the DLL and display its output. from s 문을 수동으로 입력하는 경우 superfastcode가 완성 목록에 표시되며, import를 입력하고 나면 fast_tanh 메서드가 나타납니다.If you type the from s statement manually, you'll see superfastcode come up in the completion list, and after typing import the fast_tanh method appears.

    from superfastcode import fast_tanh    
    test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d]')
    
  2. Python 프로그램을 실행하여 C++ 루틴이 Python 구현보다 약 5~20배 더 빠르게 실행되는 것을 확인할 수 있습니다.Run the Python program and see that the C++ routine runs 5 to 20 times faster than the Python implementation. 차이가 더 분명해지도록 다시 COUNT 변수를 늘려 보세요.Again, try increasing the COUNT variable so that the differences are more pronounced. 또한 디버그 빌드는 덜 최적화되고 다양한 오류 검사를 포함하기 때문에 C++ 모듈의 릴리스 빌드가 디버그 빌드보다 더 빠릅니다.Also note that a Release build of the C++ module runs faster than a Debug build because the Debug build is less optimized and contains various error checks. 그러한 구성을 자유롭게 전환하여 비교해 보세요.Feel free to switch between those configurations for comparison.

C++ 코드 디버그Debug the C++ code

Visual Studio는 디버깅 Python 및 C++ 코드를 함께 지원합니다.Visual Studio supports debugging Python and C++ code together.

  1. 솔루션 탐색기에서 Python 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성, 디버그 탭을 차례로 선택한 다음 디버그 > 네이티브 코드 디버깅 사용 옵션을 선택합니다.Right-click the Python project in Solution Explorer, select Properties, select the Debug tab, and then select the Debug > Enable native code debugging option.

    네이티브 코드 디버깅을 사용하면 프로그램이 완료되었을 때 일반적인 “계속하려면 아무 키나 누르세요.” 일시 중지를 제공하지 않고 Python 출력 창이 바로 사라질 수 있습니다.When you enable native code debugging, the Python output window may disappear immediately when the program has completed without giving you the usual "Press any key to continue..." pause. 강제로 일시 중지하려면 네이티브 코드 디버깅을 사용할 때 디버그 탭의 실행 > 인터프리터 인수 필드에 -i 옵션을 추가합니다.To force a pause, add the -i option to the Run > Interpreter Arguments field on the Debug tab when you enable native code debugging. 이 인수는 코드가 완료된 후 Python 인터프리터를 대화형 모드로 전환하며, 이때 Ctrl+Z, Enter 키를 눌러 종료할 때까지 대기합니다.This argument puts the Python interpreter into interactive mode after the code finishes, at which point it waits for you to press Ctrl+Z, Enter to exit. 또는 Python 코드를 수정하지 않으려면 프로그램의 끝에 import osos.system("pause") 문을 추가할 수 있습니다.(Alternately, if you don't mind modifying your Python code, you can add import os and os.system("pause") statements at the end of your program. 이 코드는 원래 일시 중지 프롬프트를 복제합니다.This code duplicates the original pause prompt.)

  2. 파일 > 저장을 선택하여 속성 변경 내용을 저장합니다.Select File > Save to save the property changes.

  3. Visual Studio 도구 모음에서 빌드 구성을 디버그로 설정합니다.Set the build configuration to Debug in the Visual Studio toolbar.

    빌드 구성을 디버그로 설정

  4. 코드는 일반적으로 디버거에서 실행하는 데 더 많은 시간이 걸리기 때문에 .py 파일의 COUNT 변수를 약 5배 더 작은 값으로 변경하려고 할 수 있습니다(예를 들어 500000에서 100000으로 변경).Because code generally takes longer to run in the debugger, you may want to change the COUNT variable in your .py file to a value that's about 5 times smaller (for example, change it from 500000 to 100000).

  5. C++ 코드에서는 tanh_impl 메서드의 첫 줄에서 중단점을 설정한 다음 디버거를 시작합니다(F5 또는 디버그 > 디버깅 시작).In your C++ code, set a breakpoint on the first line of the tanh_impl method, then start the debugger (F5 or Debug > Start Debugging). 해당 코드가 호출되면 디버거가 중지합니다.The debugger stops when that code is called. 중단점이 적중되지 않는 경우 구성이 디버그로 설정되어 있는지, 프로젝트를 저장했는지 확인합니다(디버거를 시작할 때 자동으로 수행되지 않음).If the breakpoint is not hit, check that the configuration is set to Debug and that you've saved the project (which does not happen automatically when starting the debugger).

    C++ 코드의 중단점에서 중지

  6. 이때 C++ 코드를 단계별로 실행하고 변수를 검사하는 등의 작업을 수행할 수 있습니다.At this point you can step through the C++ code, examine variables, and so on. 이러한 기능은 Python과 C++로 디버깅에 자세히 설명되어 있습니다.These features are detailed in Debugging C++ and Python Together.

대체 방법Alternative approaches

아래 표에 설명된 대로 다른 방법으로 Python 확장을 만들 수 있습니다.There are a variety of means to create Python extensions as described in the table below. CPython에 대한 첫 번째 항목은 이 항목에서 이미 설명했습니다.The first entry for CPython is what's been discussed in this topic already.

방법Approach 연도Vintage 담당자Representative User(s) 장점Pro(s) 단점Con(s)
CPython용 C/C++ 확장 모듈C/C++ extension modules for CPython 19911991 표준 라이브러리Standard Library 광범위한 설명서 및 자습서.Extensive documentation and tutorials. 전체 제어.Total control. 컴파일, 이식성, 참조 관리.Compilation, portability, reference management. 높은 C 지식.High C knowledge.
SWIGSWIG 19961996 crfsuitecrfsuite 한 번에 여러 언어에 대한 바인딩 생성.Generate bindings for many languages at once. Python이 유일한 대상일 경우 과도한 오버헤드.Excessive overhead if Python is the only target.
ctypesctypes 20032003 oscryptooscrypto 컴파일 안 함, 광범위한 가용성.No compilation, wide availability. 번거로운 C 구조체 액세스 및 변경과 오류 발생 가능성.Accessing and mutating C structures cumbersome and error prone.
CythonCython 20072007 gevent, kivygevent, kivy Python과 유사.Python-like. 높은 완성도.Highly mature. 고성능.High performance. 컴파일, 새 구문 및 도구 체인.Compilation, new syntax and toolchain.
cfficffi 20132013 cryptography, pypycryptography, pypy 간편한 통합, PyPy 호환성.Ease of integration, PyPy compatibility. 새로운 방법, 완성도 낮음.New, less mature.