在C++中嵌入 python 串行控制器

Embedding python serial controller in C++

本文关键字:控制器 python C++      更新时间:2023-10-16

我已经搜索了几个小时,试图让这段代码正常工作,但我似乎不太明白。

我正在C++开发一个函数,我可以在其中调用许多 python 脚本之一,这些脚本具有可变数量的参数。Python 可以工作,但我的C++中不断出现段错误。

  double run_python(motor_command command){
    //A routine that will run a python function that is in the same directory.
    Py_Initialize();
    PySys_SetPath(".");
    string pyName; //Declaration of the string and int
    int speed;
    if (command.action == READ){
        pyName = "read_encoders"; //Name of one python module
    }else{
        pyName = "drive_motor"; //Name of the other python module
        speed = command.speed;  //struct
    }
    int board_address = command.board_address;
    int motor = command.motor_num;
    //PyObject* moduleName = PyString_FromString(pyName.c_str()); 
    //  Py_INCREF(myModule);
    //PyObject* myFunction = PyObject_GetAttrString(myModule, "run"); //Both of these python functions have subroutine 'run'
    PyObject* args;
    if(command.action == READ){
        args = PyTuple_Pack(2,PyInt_FromLong(board_address),PyInt_FromLong(motor)); //Appropriate args for the read_encoders
    }else{
        args = PyTuple_Pack(3,PyInt_FromLong(board_address),PyInt_FromLong(motor), PyInt_FromLong(speed)); //Appropriate args for the drive_motor
        }
    Py_INCREF(args);
    cout << "I got here" << endl;
    PyObject* myModule = PyImport_Import((char*)pyName.c_str());//Python interface
    cout << "args = " << args << " modlue = " << myModule << endl;
    //Py_INCREF(myModule);
    PyObject* myResult = PyObject_CallObject(myModule, args); //Run it and store the result in myResult
    Py_INCREF(myResult);
    double result = PyFloat_AsDouble(myResult);
    Py_DECREF(myResult);
    return result;
}

到目前为止,我能弄清楚的是,不知何故我的 myModule 没有正确导入并返回 NULL 值。结果,当我尝试_CallObject时,它会抛出一个段错误,我就上了一条小溪。当我取消对 myModule 的Py_INCREF时,它会在那里抛出一个段错误,所以我想我没有正确导入我的 python 代码。

哦,有用的信息:操作系统:Angstorm Linux,在MinnowBoard(x86架构)上。

python程序的一般结构:

import sys
import serial
board_num = sys.argv[1]
motor = sys.argv[2]
speed = sys.argv[3]

def run(board_num, motor, speed):
    # Command arguments: Board number (0x80, 0x81...), motor number (0 or 1) and speed(2's complement signed integer)
    ser = serial.Serial('/dev/ttyPCH1', 38400)
    motor_min = 0
    motor_max = 1 # These are the two acceptable values for motor enumerated values. 
    e_code = -1 # Error code
    try:
        board_num = int(board_num, 0)
    except:
        print "Invalid address format: Must be a number"
        exit(e_code)
    try:
        motor = int(motor, 0)
    except:
        print "Motor must be either motor 0 or 1. Or possibly one or two..."
        exit(e_code)
    try:
        speed = int(speed, 0)
    except:
        print "Motor speed must be an integer."
        exit(e_code)
    #print board_num

提前谢谢你!如果您有任何其他方法可以使其以相同的方式工作,我愿意接受建议!

尝试将 . 附加到您的 sys.path:

PyObject *sys_path; 
PyObject *path; 
sys_path = PySys_GetObject("path"); 
path = PyString_FromString(".") 
if (PyList_Append(sys_path, path) < 0) 

来源: http://www.gossamer-threads.com/lists/python/dev/675857

老:首先尝试单独执行 Python 脚本,在命令行上使用 python。从 C/C++ 程序中调试 Python 错误更难。你安装了pySerial吗?