第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何擁有在Python C / C ++擴展之間共享的全局C / C ++變量?

如何擁有在Python C / C ++擴展之間共享的全局C / C ++變量?

慕村225694 2021-03-11 14:12:27
我?guī)缀跬耆肅 ++編寫了一個Python包。這樣做的原因是因為我想手動包裝現(xiàn)有的C ++庫,但這與此處無關。這個Python軟件包包含許多不同的擴展模塊,我用distutils在“ setup.py”腳本中對所有這些擴展模塊進行了編譯。這些擴展模塊可以相互關聯(lián),在這種情況下,我通過將共享庫傳遞給Extension構造函數來鏈接它們。為了清楚起見,假設我有兩個Python C ++模塊A和B,其中B使用A中定義的函數。這些函數通常編譯為A.so和B.so。由于B使用A中定義的函數,因此我照常編譯A模塊,然后將':A.so'作為庫傳遞給B模塊的Extension構造函數中的librarys關鍵字。(“:”使g ++處理該庫不是以通常的“ lib”前綴開頭的事實。)這對于鏈接函數和類是很好的。我的問題如下:我在A中定義了一些全局C ++變量。雖然我所做的描述允許B訪問A中的函數,但實際上似乎為A中定義的任何全局數據創(chuàng)建了COPY。這是一個實際的問題。為了我。在我看來,此問題本質上類似于在共享庫中使用全局變量,如此處和其他地方所討論。該解決方案以及我在網上找到的其他解決方案似乎都無法解決問題。
查看完整描述

3 回答

?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

我猜想pythonic的方法是讓不同的擴展通過C API進行交互。盡管我對c ++不太了解,但我想它與C中的解決方案并沒有太大區(qū)別。我可以通過以下方式做到這一點:

  • 在模塊A中定義全局變量

  • 為模塊A定義一個C API,其中包含指向全局變量的指針(如果需要,還可以包含一個宏,以方便使用)。

  • 在模塊B中加載C API并通過指針訪問全局變量。

編寫用于python C擴展的C API涉及到一些工作。(如果您不熟悉Python C API,請閱讀python文檔。)我建議的解決方案的最小示例如下所示:

A.h

/* Header file for A module */


#ifndef A_MODULE_H

#define A_MODULE_H

#ifdef __cplusplus

extern "C" {

#endif


#define PyA_GET_X() (*x_ptr)

#define PyA_SET_X(x) (*x_ptr = x)


#ifdef A_MODULE

/* do nothing for this minimal example */

#else

static void **PyA_API;

#define x_ptr ((long *)PyA_API[0])


static int import_A(void)

{

    PyA_API = (void **)PyCapsule_Import("A._C_API", 0);

    return (PyA_API != NULL) ? 0 : -1;

}

#endif /* !defined(A_MODULE) */

#ifdef __cplusplus

}

#endif

#endif /* !defined(A_MODULE_H) */

A.c


#include <Python.h>

#define A_MODULE

#include "A.h"


long x = 0; /* here is the global variable */


static PyObject* 

set_x(PyObject *self, PyObject *args){

    if (!PyArg_ParseTuple(args, "l", &x)) return NULL;

    Py_RETURN_NONE;

}


static PyObject* 

get_x(PyObject *self, PyObject *args){

    return PyInt_FromLong(x);

}


static PyMethodDef methods[] = {

    {"set_x", (PyCFunction)set_x, METH_VARARGS, ""},

    {"get_x", (PyCFunction)get_x, METH_NOARGS, ""},

    {NULL, NULL, 0, NULL}

    };


#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */

#define PyMODINIT_FUNC void

#endif

PyMODINIT_FUNC initA(void){

    PyObject *m = Py_InitModule3("A", methods, "");

    static void *PyA_API[1];

    PyA_API[0] = (void *)&x;


    PyObject *c_api_object = PyCapsule_New((void *)PyA_API, "A._C_API", NULL);

    if (c_api_object != NULL) PyModule_AddObject(m, "_C_API", c_api_object);

}

B.c


#include <Python.h>

#define B_MODULE

#include "A.h"


static PyObject* 

set_x(PyObject *self, PyObject *args){

    long y;

    if (!PyArg_ParseTuple(args, "l", &y)) return NULL;

    PyA_SET_X(y);

    Py_RETURN_NONE;

}


static PyObject* 

get_x(PyObject *self, PyObject *args){

    return PyInt_FromLong(PyA_GET_X());

}


static PyMethodDef methods[] = {

    {"set_x", (PyCFunction)set_x, METH_VARARGS, ""},

    {"get_x", (PyCFunction)get_x, METH_NOARGS, ""},

    {NULL, NULL, 0, NULL}

    };


#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */

#define PyMODINIT_FUNC void

#endif

PyMODINIT_FUNC initB(void){

    import_A();

    Py_InitModule3("B", methods, "");


}

setup.py


from numpy.distutils.core import setup, Extension


setup(

    name="AB",

    ext_modules = [Extension('A', ['A.c']), Extension('B', ['B.c'])],

    )

最后,您將能夠x從兩個模塊(C級或python)讀取和修改。在python中,它看起來像:


>>> import A, B

>>> A.set_x(1)

>>> B.get_x()

    1

>>> B.set_x(2)

>>> A.get_x()

    2

要從C級訪問,請使用宏PyA_GET_X()和PyA_SET_X(x)。


查看完整回答
反對 回復 2021-03-31
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

如果可以從python代碼調用c ++函數,則只需創(chuàng)建一個將訪問全局變量的函數即可。


查看完整回答
反對 回復 2021-03-31
  • 3 回答
  • 0 關注
  • 268 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號