(with code) 시작하기 | Python을 사용하여 C/C++ 코드를 호출하는 방법

편집자 추천

이전 글에서 파이썬 스크립트를 호출하기 위해 C/C++를 사용하는 방법을 소개했고 , 이 글에서는 개발에서 또 다른 일반적인 문제를 채울 것입니다. 우리가 파이썬을 개발에 사용할 때 일부 알고리즘은 계산 집약적이므로 실행 시간이 너무 오래 걸리므로 이러한 알고리즘을 C/C++ 언어로 구현하여 프로그램 실행 시간을 줄일 수 있습니다.

Python을 사용하는 것은 매우 편리하지만 C/C++만큼 효율적이지는 않습니다. 게다가 때로는 일부 중요한 코드를 보호하고 싶고 이러한 코드를 C/C++ 동적 라이브러리로 컴파일한 다음 Python을 사용하여 can을 호출할 수 있습니다. 이 목표를 아주 잘 달성하십시오.

일반적으로 일반적으로 사용되는 두 가지 구현 방법이 있습니다:
Python 확장을 사용하여 C/C++ 코드를 작성하고 가져오기를 사용하여 동적 라이브러리를 호출합니다
.Python의 ctypes 모듈을 사용하여 C/C++ 동적 라이브러리를 직접 로드합니다(공통 C/C++ 코드 사용). 작성방법).

모두 동적 라이브러리로 컴파일되지만 C/C++ 코드 작성에 큰 차이가 있습니다.

다른 구현 방법의 차이점

첫 번째 방법은 파이썬이 C/C++ 언어에 국한되지 않고 다른 언어를 통합하기 위한 확장 메커니즘이고 개인적으로 두 번째 방법이 이해하고 구현하기 쉽다고 생각합니다(보통 기존 C/C++ 코드를 수정할 필요가 없습니다) 재작성 또는 소량만 재작성) 오늘은 이러한 방식으로 구체적인 구현 프로세스를 소개하겠습니다.

첫 번째 방법의 구현에 대해서는 https://docs.python.org/zh-cn/3/c-api/intro.html을 참조하십시오.

이 시점에서 많은 학생들이 Cython이라고 말할 수 있습니다. 예, Cython은 Python/ctypes의 일련의 문제(예: 속도 병목 현상)를 해결하지만 간단한 작업을 시작하면 너무 많은 학습 비용이 허용되지 않을 수 있으며 ctypes는 특히 C/C++ 및 Python 경험이 있는 프로그래머의 경우 간단한 작업을 수행하고 빠르게 실행하는 데 더 좋습니다. Cython 및 ctypes 선택에 대해서는 여기를 참조하십시오: https://www.codenong.com/1942298/

도서관에 대한 간략한 소개

라이브러리의 본질은 패키지화된 코드 패키지로, 일반적으로 정적 라이브러리(.lib .a)와 동적 라이브러리(.dll .so)로 나눌 수 있습니다. 리눅스 환경에서 접미사. . 정적 라이브러리는 메인 프로그램이 컴파일될 때 최종 실행 파일로 컴파일되고 동적 라이브러리는 호출 시 관련 콘텐츠를 검색합니다. ctypes는 정적 라이브러리를 호출할 방법이 없기 때문에 이번에는 C/C++를 동적 라이브러리로 컴파일합니다.

기본 사용법

개인적으로 ctypes를 사용하는 것의 장점은 편리함과 약간의 수정으로 큰 성능 향상을 가져올 수 있다는 점이라고 생각하며 효율성과 성능의 균형 아래에서 최적의 선택입니다. 호출 프로세스는 일반적으로 두 단계로 나뉩니다:
1. C/C++ 코드를 동적 라이브러리로 컴파일하고
2. Python을 사용하여 해당 동적 라이브러리를 호출합니다.

C/C++ 코드를 동적 라이브러리로 컴파일

CMake는 다음을 수정해야 합니다.

add_library(c_library SHARED src/c_library.cpp)

여기서 SHARED는 동적 링크 라이브러리를 의미합니다.

ctypes는 #define 상수와 사용 중인 라이브러리의 항목에 대해 알지 못하므로 함수만 알고 있으므로 자신의 코드에서 해당 상수를 재정의해야 합니다.

간단한 합계 코드는 다음과 같습니다(이름: c_library.cpp).

#include <stdio.h>

extern "C"
{
    
    
    int add_int(int num1, int num2)
{
    
    
        return num1 + num2;
    }

    float add_float(float num1, float num2)
{
    
    
        return num1 + num2;
    }
}

C++ 함수를 호출할 때 함수 선언에 접두어 extern "C"를 추가해야 함은 C++에서 함수 오버로딩 함수를 지원하고 컴파일 중에 함수 이름이 변경되기 때문입니다. 따라서 함수가 선언될 때 코드가 C 방식으로 컴파일되도록 기본적으로 접두사 extern "C"를 추가합니다.

컴파일하면 생성된 동적 라이브러리가 아래 그림과 같습니다.

여기에 이미지 설명 삽입

Python을 사용하여 동적 라이브러리 호출

Python이 동적 링크 라이브러리를 호출하는 프로세스는 일반적으로
1. 동적 링크 라이브러리 로드,
2. 입력을 C 호환 데이터 유형으로 변환,
3. 출력을 C 호환 데이터 유형으로 변환,
4 단계로 나뉩니다. .동적 라이브러리 함수를 호출합니다.

전체 코드는 다음과 같습니다.

import ctypes
import os
import sys

#Load the shared object file
if sys.platform == "win32":
    c_library = ctypes.CDLL(os.path.abspath(
        '.')+"/out/build/x64-Debug/c_cxx/c_library/libc_library.dll")
    print
elif sys.platform == "linux":
    c_library = ctypes.CDLL(os.path.abspath(
        '.')+"/build/c_cxx/c_library/libc_library.so")

#Find sum of integers
res_int = c_library.add_int(4, 5)
print("Sum is : " + str(res_int))

#Find sum of floats
a = ctypes.c_float(5.5)  # 输入转换为C兼容的数据类型
b = ctypes.c_float(4.1)

c_library.add_float.restype = ctypes.c_float  # 输出转换为C兼容的数据类型

print("Sum is : ", str(c_library.add_float(a, b)))

내 기억이 맞다면 int 유형은 변환할 필요가 없으므로 코드를 작성하지 않았습니다.

Python 코드를 실행하면 결과는 다음과 같습니다.

여기에 이미지 설명 삽입
더 많은 ctypes 관련 작업은 https://docs.python.org/3/library/ctypes.html을 참조하십시오.

일반적으로 사용되는 변수 유형과 ctypes의 C 유형 간의 대응 테이블:

여기에 이미지 설명 삽입

참조

1.https://zhuanlan.zhihu.com/p/36772947
2.https://blog.csdn.net/u012247418/article/details/80170690

Supongo que te gusta

Origin blog.csdn.net/weixin_41006390/article/details/126459715
Recomendado
Clasificación