我想从我的C代码中管理一个LCD来调用python。我是新手。
我的python应用程序与LCD完美结合。我的python代码中使用的库没有问题。蟒蛇2.7
当我调用PyModule_GetDict函数时,我的问题就出现了。如果我在python文件中添加了一个特定的库导入,我的C程序就会崩溃。
这个库是Adafruit_i9341,如果我不导入它,C程序就会正常运行。
有没有可能存在与Python interpeter不兼容的库?
如何调试此问题?
谢谢!
这是我的C代码:
// Set PYTHONPATH TO working directory
setenv("PYTHONPATH",".",1);
PyObject *pName, *pModule, *pDict, *pFunc, *presult;
// Initialize the Python Interpreter
Py_Initialize();
// Build the name object
pName = PyString_FromString((char*)"lcd");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, (char*)"initLCD");
if (PyCallable_Check(pFunc)) {
printf("Let's give this a shot!\n");
presult=PyObject_CallObject(pFunc,NULL);
PyErr_Print();
} else {
PyErr_Print();
}
printf("Result is %d\n",PyInt_AsLong(presult));
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
这是python代码:
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import os
import threading
from threading import Timer
import Adafruit_ILI9341 as ADAFRUIT_TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import RPi.GPIO as LCD_GPIO
import time
import locale
def iniciaDisplay():
LCD_GPIO.setwarnings(False)
LCD_GPIO.setmode(LCD_GPIO.BCM)
LCD_GPIO.setup(5, LCD_GPIO.OUT)
p = LCD_GPIO.PWM(5, 100)
p.start(1)
DC = 24
RST = 25
SPI_PORT = 0
SPI_DEVICE = 0
disp = ADAFRUIT_TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=64000000))
disp.begin()
disp.clear()
disp.display(getLogo(0))
return 0
编辑:
根据@BlackJack的建议,我添加了空检查和PyErr_打印,我看到了失败的原因。问题是由io库导入引起的。
这是检查空值和PyErr_打印的输出:
Traceback (most recent call last):
File "/home/pi/pruebas/DESFIREXip32/tft.py", line 18, in <module>
import Adafruit_ILI9341 as ADAFRUIT_TFT
File "build/bdist.linux-armv7l/egg/Adafruit_ILI9341/__init__.py", line 21, in <module>
File "build/bdist.linux-armv7l/egg/Adafruit_ILI9341/ILI9341.py", line 23, in <module>
File "/usr/lib/python2.7/dist-packages/numpy/__init__.py", line 153, in <module>
from . import add_newdocs
File "/usr/lib/python2.7/dist-packages/numpy/add_newdocs.py", line 13, in <module>
from numpy.lib import add_newdoc
File "/usr/lib/python2.7/dist-packages/numpy/lib/__init__.py", line 22, in <module>
from .npyio import *
File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 4, in <module>
from . import format
File "/usr/lib/python2.7/dist-packages/numpy/lib/format.py", line 141, in <module>
import io
File "/usr/lib/python2.7/io.py", line 51, in <module>
import _io
SystemError: _PyImport_FixupExtension: module _io not loaded
我认为这个错误应该换个思路来处理。
最佳答案
我发现至少有五个问题,除了两个以外,其他所有问题都没有检查NULL
值。
您没有检查PyImport_Import()
的返回值。如果在导入lcd
模块时出现问题/异常,则代码将继续,就像没有发生任何事情一样。
而且PyDict_GetItemString()
的返回值并没有真正对照NULL
进行检查。PyCallable_Check()
被应用,但它有点多余,因为PyObject_CallObject()
已经检查参数是否可调用。
当然,如果PyObject_CallObject()
的返回值是NULL
的话,您不会检查它。PyErr_Print()
可能会被调用,即使没有错误/异常,文档清楚地指出这将导致致命错误。
最后用一个可能未初始化的指针调用PyInt_AsLong()
。给定示例代码,它被定义为未初始化,因为Python代码不包含presult
所以initLCD()
是pFunc
并且NULL
永远不会被赋值。
因此,您最好将每个指针初始化为presult
并检查每个返回值。
PyObject *pName = NULL;
PyObject *pModule = NULL;
PyObject *pFunc = NULL;
PyObject *presult = NULL;
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
if ((pName = PyString_FromString("lcd"))) {
if ((pModule = PyImport_Import(pName))) {
if ((pFunc = PyObject_GetAttrString(pModule, "initLCD"))) {
if ((presult = PyObject_CallObject(pFunc, NULL))) {
printf("Result is %d\n", (int) PyInt_AsLong(presult));
}
}
}
}
if (PyErr_Occurred()) PyErr_Print();
Py_XDECREF(presult);
Py_XDECREF(pFunc);
Py_XDECREF(pModule);
Py_XDECREF(pName);
Py_Finalize();