pModule이 Null이 나온다면 import부터 체크해보자
탭으로 구분되어있나 띄어쓰기로 되어있나
제대로 def main이 되어있나
---------------------------------------------------------
20200805 추가
하위디렉토리로 만약에 파이썬파일이 import 되어있다면 ...
가정 1. 하위디렉토리 명은 abc이다.
가정 2. c에서 콜할 메인에서 import abc 를 하고 있다
가정 3. ./abc/in.py라는 파일안에 클래스가 선언되어있다.
가정 4. in.py 안에 import abc.utils 등으로 import 되어있다.
---> 수정하는 방법
c파일인 main.c에서 path를 한번더 추가시켜줘야한다.
PyList_Append(pPath, PyUnicode_FromString("메인함수있는경로")
-> 추가필요 : PyList_Append(pPath, PyUnicode_FromString("메인함수있는경로/abc")
를 추가해야한다.
가정2에서 import abc -> import in 으로 바꾼다.
가정4에서 import abc.utils -> import utils로 바꾼다.
---------------------------------------------------------------------
20200515 추가
개인적으로 소스 파일을 수정한 것을 적어놓는다.
- 전체 main을 만들고 그 안에서 초기화 및 데이터 넣어주는 작업을 했는데 같은 영역 안에있어도 값이 달랐다.
def main
a
func(a)
a
이런 형태라고 하면 func을 거친 a는 값이 달라져야하는데 안달라져있었다. 그렇기 때문에
def main
a
a = func(a)
a
아래와 같은 방법을 취했고 func에는 return 값을 주었다.
밑에는 c소스 이다. 이 소스는 파이썬한테 아규먼트를 전달하여 실행을 시키고 결과 값을 받아오게 할 수 있는 소스이다.
c 소스에서 중요한점
1. 경로설정
2. 파이썬에서 return 받는 값이 있어야한다.(파이썬에서 주는 형식을 그대로 받고 싶다) [0, 1, 2, ...] or TEXT or 100.00
3. return 값에 따라 다르게 pValue를 받아올 수 있다.
실행시킬 python 소스에서 중요한점
1. return 의 데이터 타입. c가 받는 형식대로 뿌려줘야한다. 문자열이면 문자열, 숫자면 숫자
2. sys.argv와 self의 기능을 사용할 수가 없다(나는 그러했다)
3. ./a.out mypython main 1 2 3 이런식을 실행시킬 수 있다.
a.out은 실행파일
mypython은 파이썬 소스 파일(mypython.py)
main은 파이썬 내에 선언된 함수(def main(a, b, c):)
print(a) print(b) print(c)를 할 경우 1 2 3이 출력된다.
4. 위와 같은 이유로 어쩔 수 없이 수정이 되어야하며 나의 경우는 def main을 따로 만들어서 아규먼트를 받아오고 init을 했으며 소스의 플로우대로 실행시켜나갔다.
-----------------------
Exception ignored in: <module 'threading' from '/usr/lib64/python3.6/threading.py'>
Traceback (most recent call last):
File "/usr/lib64/python3.6/threading.py", line 1289, in _shutdown
assert tlock.locked()
SystemError: <built-in method locked of _thread.lock object at 0x7ff2db729878> returned a result with an error set
위와같은 오류 때문에 애먹었는데 c와 python의 리턴주고 받는 데이터 형식이 달라서 였다.
세그멘테이션 폴트는 흔하게 발생할 것이다.
#include<stdio.h>
#include<Python.h>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc, *pPath, *pDict;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
return 1;
}
// Initialize the Python Interpreter
// Python 인터프리터 초기화
Py_Initialize();
// unix 에서는 현재 경로에 python source(??.py) 가 있더라도
// 반드시 경로를 지정 하여야 한다.
pPath = PySys_GetObject("path");
PyList_Append(pPath, PyUnicode_FromString( "/home/changjo/pytoc" ));
pName = PyUnicode_DecodeFSDefault(argv[1]);
//pName = PyUnicode_FromString(argv[1]);
pModule = PyImport_Import(pName);
pDict = PyModule_GetDict(pModule);
//pFunc = PyDict_GetItemString(pDict, argv[2]);
/* Error checking of pName left out */
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyUnicode_FromString(argv[i + 3]); // string형태로 넣어주는 방법
//pValue = PyLong_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
printf("pArgs : %s\n", PyUnicode_AsUTF8(PyObject_Repr(pArgs))); // PyObject -> String
pValue = PyObject_CallObject(pFunc, pArgs);
//Py_DECREF(pArgs);
if (pValue != NULL) {
printf("pValue : %s\n", PyUnicode_AsUTF8(PyObject_Repr(pValue))); // PyObject -> String
//printf("pValue : %s\n", pValue);
//printf("Result of call: %ld\n", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
if (Py_FinalizeEx() < 0) {
return 120;
}
return 0;
}
'개발 업무(코딩)-개발자였을때 썼던..' 카테고리의 다른 글
C-JSON EXAMPLE 예제 #include<json/json.h> (0) | 2023.01.09 |
---|---|
json 불필요한 공백,탭,개행 제거 (0) | 2023.01.09 |
개발 업무..확장가능한 키움 open api(조회성) (0) | 2023.01.08 |
KIWOOM API를 이용한 주식 일자별 시세 수집(python) (0) | 2023.01.08 |
나만의 로그파일 만들기(LOG) (0) | 2023.01.08 |