我想从我的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();

08-26 20:11
查看更多