기금넷 공식사이트 - 복권 조회 - 파이썬 c API 를 사용할 때 주의해야 할 사항은 무엇입니까?

파이썬 c API 를 사용할 때 주의해야 할 사항은 무엇입니까?

1: Python 에서 쉽게 호출할 수 있도록 C API 를 사용하여 Python 에 대한 C 언어 함수를 작성합니다.

1. 먼저 특정 프로토타입으로 기능을 구현합니다. Python C API 를 사용하여 구현하는 경우 모든 함수는 이 프로토타입이어야 합니다. 꼭 이렇다.

PyObject *Fun(PyObject *self, PyObject *args)

Self 는 클래스를 사용할 때만 사용해야 합니다 (나는 쓸모가 없음). args 는 함수의 인수입니다. Args 는 PyObject* 유형이기 때문입니다 (파이썬 언어의 모든 유형을 나타낼 수 있음).

2. PyArg_ParseTuple 함수를 사용하여 매개변수를 c 언어 표현으로 변환합니다.

3. 원하는 작업을 수행한 후 PyObject* 유형 값도 반환해야 합니다. Py_BuildValue 함수에 의해 생성됩니다.

여기서 제가 말하고자하는 것은 Tuple 유형의 값을 반환하려면 사용할 수 있다는 것입니다.

Pyobject * tuple = py _ build value ("(IIS)", 1, 2, "three");

양식을 작성해야 하는데, 만약 많은 것이 있다면, 다음과 같은 방법으로 구성할 수 있습니다.

Pyobject * t;

T = pytuple _ new (3);

PyTuple_SetItem(t, 0, pylong _ from long (1l));

PyTuple_SetItem(t, 1, pylong _ from long (2l));

PyTuple_SetItem(t, 2, pystring _ from string ("three"));

이 점은 건설 초기에 오랫동안 곤혹스러웠다.

4. 출력될 모든 함수를 하나의 배열에 넣습니다. 배열의 구조는 다음과 같습니다.

구조 PyMethodDef {

Const char * ml _ name/* 내장 함수/메서드 이름 */

PyCFunction ml _ meth/* c 함수 구현 */

Int ml _ flags/* METH _ XXX 로고 조합, 메인

C func 를 설명하는 데 필요한 매개변수 */

Const char * ml _ doc/* _ _ doc _ _ 속성 또는 NULL */

}

배열은 {NULL, NULL} 로 끝납니다

5. 파이썬 가져오기 시 초기화되는 함수를 구성합니다.

비슷한

FUNC 피모디니트

Initexample(void)

{

Py_InitModule("example ",example _ methods);

}

특히 초기화 함수의 이름은 엄격하게 요구되며, init 뒤에는 모듈 이름이 와야 합니다. 그렇지 않으면 파이썬은 초기화 함수를 찾을 수 없다는 오류를 보고합니다.

확장 모듈을 작성한 후 동적 라이브러리로 컴파일합니다 (Python 은 이 동적 라이브러리의 이름이 pyd 라고 요구하지만 실제로는 접미사의 변화일 뿐입니다). 가져오는 방식으로 파이썬 스크립트에 직접 로드할 수 있습니다. 사용의 경우 이 라이브러리가 C API 확장으로 작성되었는지 아니면 Python 문으로 직접 작성되었는지 알 필요가 없습니다 (Lua 도 마찬가지임).

마지막으로 python 의 소스 코드에는 example_nt 라는 예가 첨부되어 참조로 사용될 수 있습니다. 전체 확장 코드는 다음과 같습니다.

# Python.h 포함

정적 객체 *

Ex_foo(PyObject *self, PyObject *args)

{

Printf("Hello, world/n ");

Py _ incref (py _ none);

Py _ None 을 반환합니다

}

정적 PyMethodDef example_methods[] = {

{"foo ",ex_foo, METH_VARARGS," foo() doc string"},

{NULL, NULL}

}

FUNC 피모디니트

Initexample(void)

{

Py_InitModule("example ",example _ methods);

}

2. c 언어로 파이썬 문 호출

먼저 void Py_Initialize () 는 초기화에 사용되고 void Py_Finalize () 는 파이썬 호출을 종료하는 데 필요합니다.

불타는 불은 두 가지 상황이 있다. PyRun _ 이라는 접두사가 붙은 함수는 몇 문장일 경우 유용합니다. 예를 들면 다음과 같습니다

Intpyron _ simplestring (constchar * command)

함수는 char* 의 Python 문을 직접 실행할 수 있습니다.

반환 값을 얻어야 하는 경우

Pyobject * pyron _ string (constchar * str, int start, PyObject *globals, PyObject *locals)

또한 매우 유용합니다. 위의 두 함수는 파일에 있을 때 파이썬 소스 코드가 이미 메모리로 읽혀진 경우를 처리하는 데 사용됩니다.

Int pyron _ simple FILE(FILE * FP, const char *filename)

Py object * pyron _ File(File * FP, const char *filename, int start, PyObject *globals, pyobject *)

비슷한 것을 사용하다. 말을 많이 하지 않다.

모듈 (예: 함수) 인 경우 C 언어로 호출하려면 사용하기가 좀 더 복잡합니다. 이 경우 C 언어에서 Python 함수로 매개 변수를 전달하고 실행하여 결과를 얻을 수 있어야 합니다.

다음은 몇 가지 상황입니다.

파일, 메모리, 컴파일, 소스 코드

서류에서 쉽게 해결할 수 있습니다. 위와 같습니다. 여기서는 주로 기억 속의 상황을 이야기한다. 사실, 해결책을 찾는 데 오랜 시간이 걸렸습니다. ) 을 참조하십시오

컴파일되지 않은 경우: (즉, 소스 코드)

1. 합격

Pyobject * py _ compilestring (constchar * str, const char *filename, int start)

먼저 API 를 컴파일합니다. 이 API 의 매개변수를 설명하겠습니다. Str 은 메모리의 소스 코드이며 filename 은 주로 오류에 사용됩니다. 사실 테스트 결과, 문자열을 아무거나 줘도 상관없지만 빈 매개 변수를 주면 런타임 오류가 발생할 수 있습니다. Start 나는 보통 Py_file_input 을 사용한다. 왜냐하면 파일에서 실제로 읽었기 때문이다. 반대로 Py_single_input 은 명령문을 나타내는 데 사용되며 Py_eval_input 의 사용법은 잘 모르겠다.

이 함수는 소스 코드를 호출한 후 컴파일된 PyObject* 를 얻습니다. (사실 소스 코드를 따라가면 PyCodeObject 구조입니다. ) 이름을 lpCode 로 지정해야 합니다.

2. API 를 다시 호출합니다.

Pyobject * pyimport _ execcodemodule (char * name, PyObject *co)

모듈을 가져옵니다. 인수는 또한 name 이 가져오기 모듈의 이름이고 co 는 이전에 컴파일된 코드 객체 (lpCode) 임을 설명합니다. 모듈 객체를 반환합니다. 이름이 lpMod 라고 가정합니다.

3. API 를 다시 호출합니다

Pyobject * pyobject _ getattrstring (pyobject * o, const char *attr_name)

함수 객체를 가져옵니다. O 는 모듈 개체 (lpmod) 이고 attr _ name 은 호출할 함수 이름입니다. Main 이라는 함수를 "main" 이라고 가정하고 lpFun 이라는 이름을 가정하여 함수 객체를 반환합니다.

4. 이때 API 를 사용할 수 있습니다.

Int PyCallable_Check(PyObject *o)

함수를 얻었는지 확인하십시오. 확실하다면 직접 이용하실 수 있습니다.

PyObject_Call 로 시작하는 lpFun 이라는 함수 집합. 이러한 함수에는 많은 것들이 포함되어 있으며, 일반적인 입력 매개변수는 다르지만 효과는 동일하지만 함수만 호출됩니다. 매개 변수는 일반적으로 위에서 언급한 build 함수를 통해 얻을 수 있으며 반환 값은 PyObject* 이며 PyArg_ function 을 통해 얻을 수 있지만 매개 변수를 분석하는 데 별로 좋지 않은 것 같습니다. Py[type]_As 와 같은 함수를 사용하여 유형을 결정하는 것이 좋습니다 (type 으로 가정).

예를 들면 다음과 같습니다.

Long pylong _ aslong (pyobject * pylong) 이 길어집니다.

Doublepylong _ as double (pyobject * pylong) 은 double 을 얻습니다.

여기서 말하고자하는 것은 소스 코드에서 직접 함수 호출 객체를 얻는 방법이 있어야하지만 직접 시도하지 않았다는 것입니다. 만약 누군가가 알고 있다면, 의견을 좀 주십시오!

컴파일된 코드:

컴파일된 코드의 경우 컴파일된 PyCodeObject 객체를 가져오는 것은 위와 다릅니다. 물론 소스 코드에서 PyObject* 를 표현하는 방법은 다릅니다 (위 예의 LP 코드).

물론 나중에 컴파일된 LP 코드를 얻으려면 먼저 컴파일해야 합니다. 하지만 pyc 로 끝나는 파일로 컴파일되어 메모리를 직접 읽은 후 PyCodeObject 개체로 변환할 방법을 찾지 못했습니다. (누군가 알고 계시길 바랍니다. 알려주시기 바랍니다! ) 을 참조하십시오

내가 찾은 방법은 먼저 쓰는 것이다.

Pyobject * pymarshal _ writeobject tostring (pyobject * value, int version)

Void PyMarshal _ WriteLongToFile (long 값, FILE *file, int 버전)

이 두 함수는 먼저 PyCodeObject 객체 (lpCode) 를 파일이나 메모리로 직렬화합니다.

그런 다음 필요한 경우 이 기능을 사용합니다.

Pyobject * pymarshal _ readobjectfromfile (파일 * 파일)

Pyobject * pymarshal _ readobjectfromstring (char * string, Py_ssize_t len)

읽어보면, 읽은 PyObject* 는 실제로 원하는 pycodeobject (LP 코드) 입니다. 다음 단계는 컴파일되지 않은 단계와 동일합니다.

나는 사장이 준 자료의 절반을 참고하여 이런 왜곡된 방법을 반복적으로 연구했다. 그리고 나는 여전히 정말로 직접적이고 효과적인 방법을 찾지 못했다.