C和Python之间的变量交换

时间:2018-09-07 14:07:20

标签: python c python-3.x

我最近已经阅读了很多有关它的内容,但是无法解决任何问题。这是关于从C脚本到Python 3.x的变量交换。

对于C脚本: 我正在评估IEC61850-9-2采样值(SV),并使用libiec61850 C库(https://github.com/mz-automation/libiec61850)来解释协议。 SV每周期(正弦)发送80个样本,这意味着每0.25毫秒到达一个新样本,需要对其进行处理。因此,我的脚本必须快速。

当前,我使用以下C脚本,该脚本评估协议并打印样本。 我希望这是可以理解的,并且我的评论足够:

#include "hal_thread.h"
#include <signal.h>
#include <stdio.h>
#include "sv_subscriber.h"
#include <unistd.h>

static bool running = true;
int sample_rate = 80;
double sample[2]=  { 0.0 };

void sigint_handler(int signalId)
{
    running = 0;
}

/* Callback handler for received SV messages */
static void svUpdateListener (SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU asdu)
{    
        double val1, val2, val3 = 0;
        /* read the INT32 Voltage Values on Byte Number 32 , 40 and 48*/
        val1 = (double)SVSubscriber_ASDU_getINT32(asdu, 32)/100;
        val2 = (double)SVSubscriber_ASDU_getINT32(asdu, 40)/100;
        val3 = (double)SVSubscriber_ASDU_getINT32(asdu, 48)/100;

        sample[0] = val1;
        sample[1] = val2;
        sample[2] = val2;

        printf("[%f , %f , %f ]\n", val1, val2, val3);
}

int main(){

    /* Creating a SV Receiver and setting Interface to Eth0 */
    SVReceiver receiver = SVReceiver_create();        
    SVReceiver_setInterfaceId(receiver, "eth0");

    /* Creating a SV Subscriber, which listens to SV Messages with APPID 4000h */
    SVSubscriber subscriber = SVSubscriber_create(NULL, 0x4000);

    /* Install a callback handler for the subscriber */
    SVSubscriber_setListener(subscriber, svUpdateListener, NULL);

    /* Connect the subscriber to the receiver */
    SVReceiver_addSubscriber(receiver, subscriber);

    /* Start listening to SV messages - starts a new receiver background thread */
    SVReceiver_start(receiver);

    /* Listens to Strg + C Keyboard Interruptions */
    signal(SIGINT, sigint_handler);

    /* Endless loop until Keyboard Tnterruption */
    while (running){}

    /* Stop listening to SV messages */
    SVReceiver_stop(receiver);

    /* Cleanup and free resources */
    SVReceiver_destroy(receiver);

}

现在,我想将值传递给Python进行进一步分析,并将它们另存为Numpy Array。我通过使用subprocess.popen启动C脚本并读取C脚本的sdtout并将其转换为numpy数组来解决此问题。不幸的是,这种变体太慢了,特别是因为我们可能希望以后每个周期最多增加256个样本。

Python:

process = subprocess.Popen(['sudo', folder+c_script], stdout = subprocess.PIPE, stdin = subprocess.PIPE) 

voltage_sample = numpy.empty([0,3])
voltage_data = numpy.empty((0,sample_rate * 10,4))

while True:
        output = process.stdout.readline()     
        line = numpy.array(json.loads(output.strip().decode('ascii'))).reshape(1,3)
        voltage_sample = numpy.vstack((voltage_sample, line))

因此,我的问题是:有没有更有效的方法将测量结果发送到Python?我已经读过一些有关ctypes的内容,但是根据libiec61850,回调处理程序svUpdateListener(在新样本到达时触发)是一个没有返回值的void函数。因此,没有值可以返回给Python,还是? Cython可以解决问题吗?

0 个答案:

没有答案