SylixOS Python擴展庫開發

1 適用範圍

本文檔適用於但願使用基於SylixOS進行Python擴展庫開發的用戶。python

2 SylixOS Python簡介

Python是一門面向對象的解釋型的腳本語言,Python具備豐富和強大的庫。它常被暱稱爲膠水語言,可以把用其餘語言製做的各類模塊(尤爲是C/C++)很輕鬆地聯結在一塊兒。常見的一種應用情形是,使用Python快速生成程序的原型(有時甚至是程序的最終界面),而後對其中有特別要求的部分,用更合適的語言改寫,好比3D遊戲中的圖形渲染模塊,性能要求特別高,就能夠用C/C++重寫,然後封裝爲Python能夠調用的擴展類庫。數組

目前SylixOS支持的Python爲3.6.4版本,支持絕大多數內建庫,但並未移植擴展庫。編輯器

3 SylixOS Python擴展庫開發

可擴展性是Python的一大特點,Python的擴展庫能夠基於Python語言開發,也可經過C、JAVA等語言進行開發。函數

本文將介紹如何使用RealEvo-IDE開發C語言版本的SylixOS Python擴展庫。C語言版本Python擴展庫開發有如下兩種方式。性能

3.1 基於python ctypes模塊開發

SylixOS下的Python支持ctypes內建模塊。此模塊的CDLL方法會調用SylixOS操做系統的dlopen()函數,從而導入用戶開發的C/C++動態庫。ui

編寫簡單的動態庫lib_demo,代碼如程序清單 3.1所示。spa

程序清單 3.1 動態庫demo操作系統

#include <stdio.h>對象

 

void lib_func (void)blog

{

    printf("lib_func call!\n");

}

 

void hello (void)

{

    printf("Hello SylixOS!\n");

}

 

int fact(int n)

{

    if (n <= 1)

        return 1;

    else

        return n * fact(n - 1);

}

將lib_demo編譯上傳至目標設備中。新建一個Python腳本test.py,使用VI編輯器編輯python腳本,內容以下:

import ctypes

demo=ctypes.CDLL("/lib/lib_demo.so")

print("-------------")

demo.lib_func()

print("-------------")

demo.hello()

print("-------------")

print(demo.fact(10))

print("-------------")

 

保存後執行「python test.py」,結果如圖 3.1 所示。

圖 3.1 python腳本執行結果

腳本執行結果顯示,動態庫內的函數被成功調用。

 

3.2 基於Python擴展庫模板開發

除了使用ctypes直接導入SylixOS動態庫外,python自己也提供自定義擴展庫的模板。經過模板封裝的C/C++動態庫,能夠直接使用python的「import」方法導入模塊。

依然以lib_demo爲例,首先須要添加所需頭文件的路徑。頭文件在SylixOS的/lib/python3/include目錄下提供,可自行拷貝至開發的動態庫目錄下。環境配置(以實際環境爲準)如圖 3.2 所示。

圖 3.2 選擇動態庫頭文件路徑

接着封裝動態庫,主要分爲4步:

a、包含Python頭文件;

添加頭文件:#include <Python.h>

 

b、利用樣板來包裝函數;

將lib_demo中的fact()函數封裝以下(並不是修改原函數,而是添加封裝函數)

static PyObject *lib_demo_fact(PyObject *self,PyObject *args) {

    int num;

    if(!(PyArg_ParseTuple(args,"i",&num))) {       //獲取Python傳遞的參數

        return NULL;

    }

return (PyObject*)Py_BuildValue("i",fact(num)); 

//將結果轉換爲Python類型並返回

}

 

c、爲每一個模塊增長PyMethodDef ModuleMethods[]數組;

static PyMethodDef lib_demoMethods [] = {

    {"fact",lib_demo_fact,METH_VARARGS},            //函數名,包裝函數名,解析

    {"hello",lib_demo_hello,METH_NOARGS},

    {"lib_func",lib_demo_lib_func,METH_NOARGS},

    {NULL,NULL},                                         //做爲結束

};

 

d、編寫初始化函數。

static struct PyModuleDef lib_demoModule = {

    PyModuleDef_HEAD_INIT,     //默認

    "lib_demo",                  //模塊名

    NULL,

    -1,

    lib_demoMethods             //上面的數組

};

 

PyMODINIT_FUNC

PyInit_lib_demo(void)

{

  return  PyModule_Create(&lib_demoModule);

}

 

封裝完成後的lib_demo如程序清單 3.2 所示。

程序清單 3.2 封裝完成的lib_demo

#include <Python.h>

#include <stdio.h>

 

int lib_func (void)

{

    printf("lib_func call!\n");

    return 0;

}

 

int hello (void)

{

    printf("Hello SylixOS!\n");

    return 0;

}

 

int fact(int n)

{

    if (n <= 1)

        return 1;

    else

        return n * fact(n - 1);

}

 

static PyObject *lib_demo_fact(PyObject *self,PyObject *args) {

    int num;

    if(!(PyArg_ParseTuple(args,"i",&num))) {                  //獲取Python傳遞的參數

        return NULL;

    }

    return (PyObject*)Py_BuildValue("i",fact(num));           //將結果轉換爲Python類型並返回

}

 

static PyObject *lib_demo_hello(PyObject *self,PyObject *args) {

 

    return (PyObject*)Py_BuildValue("i",hello());

}

 

static PyObject *lib_demo_lib_func(PyObject *self,PyObject *args) {

 

    return (PyObject*)Py_BuildValue("i",lib_func());

}

 

static PyMethodDef lib_demoMethods[] = {

    {"fact",lib_demo_fact,METH_VARARGS},//函數名,包裝函數名,解析

    {"hello",lib_demo_hello,METH_NOARGS},

    {"lib_func",lib_demo_lib_func,METH_NOARGS},

    {NULL,NULL},//做爲結束

};

 

static struct PyModuleDef lib_demoModule = {

    PyModuleDef_HEAD_INIT,     //默認

    "lib_demo",                //模塊名

    NULL,

    -1,

    lib_demoMethods            //上面的數組

};

 

PyMODINIT_FUNC

PyInit_lib_demo(void)

{

  return  PyModule_Create(&lib_demoModule);

}

將編譯完成後的lib_demo.so上傳至目標設備的/lib/python3/lib/python3.6/lib-dynload目錄下。建立並編輯python腳本test2.py,內容以下。

import lib_demo as demo

print("-------------")

demo.lib_func()

print("-------------")

demo.hello()

print("-------------")

print(demo.fact(10))

print("-------------")

保存後執行「python test2.py」,輸出結果如圖 3.3 所示。

圖 3.3 test2腳本執行結果

腳本運行結果顯示,lib_demo模塊能被成功導入。

相關文章
相關標籤/搜索