溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SylixOS Python擴展庫開發(fā)

發(fā)布時間:2020-07-16 20:06:58 來源:網絡 閱讀:496 作者:zhaotongchen 欄目:編程語言

1 適用范圍

本文檔適用于希望使用基于SylixOS進行Python擴展庫開發(fā)的用戶。

2 SylixOS Python簡介

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

目前SylixOS支持的Python3.6.4版本,支持絕大多數內建庫,但并未移植擴展庫。

3 SylixOS Python擴展庫開發(fā)

可擴展性是Python的一大特色,Python的擴展庫可以基于Python語言開發(fā),也可通過CJAVA等語言進行開發(fā)。

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

3.1 基于python ctypes模塊開發(fā)

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

編寫簡單的動態(tài)庫lib_demo,代碼如程序清單 3.1所示。

程序清單 3.1 動態(tài)庫demo

#include <stdio.h>

 

void lib_func (void)

{

    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("-------------")

 

保存后執(zhí)行“python test.py”,結果如 3.1 所示。

SylixOS Python擴展庫開發(fā)

 3.1 python腳本執(zhí)行結果

腳本執(zhí)行結果顯示,動態(tài)庫內的函數被成功調用。

 

3.2 基于Python擴展庫模板開發(fā)

除了使用ctypes直接導入SylixOS動態(tài)庫外,python本身也提供自定義擴展庫的模板。通過模板封裝的C/C++動態(tài)庫,可以直接使用python的“import”方法導入模塊。

依然以lib_demo為例,首先需要添加所需頭文件的路徑。頭文件在SylixOS/lib/python3/include目錄下提供,可自行拷貝至開發(fā)的動態(tài)庫目錄下。環(huán)境配置(以實際環(huán)境為準)如 3.2 所示。SylixOS Python擴展庫開發(fā)

 3.2 選擇動態(tài)庫頭文件路徑

接著封裝動態(tài)庫,主要分為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目錄下。創(chuàng)建并編輯python腳本test2.py,內容如下。

import lib_demo as demo

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

demo.lib_func()

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

demo.hello()

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

print(demo.fact(10))

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

保存后執(zhí)行“python test2.py”,輸出結果如 3.3 所示。

SylixOS Python擴展庫開發(fā)

 3.3 test2腳本執(zhí)行結果

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



向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI