2016-10-19 61 views
2

我有這樣的python類A使用C++的參數創建Python構造函數,PyObject

class A: 
    def __init__(self, name): 
     self.name = name 

    def print_lastname(self, lastname): 
     print(lastname) 

我必須這樣調用這段代碼。

import B 
a = B.A("hello") 
a.print_lastname("John") 

目前,我需要從我的C++代碼中使用這個A類。我有這麼多。

Py_Initialize(); 
string hello = "hello"; 
PyObject *module, *attr, *arg; 
module = PyObject_ImportModule("B"); // import B 
attr = PyObject_GetAttrString(module, "A"); // get A from B 
arg = PyString_FromString(hello.c_str()); 
instance = PyInstance_New(attr, arg, NULL); // trying to get instance of A with parameter "hello" 
Py_Finalize(); 

但我得到錯誤

Exception TypeError: 'argument list must be tuple' in module 'threading' from '/usr/lib64/python2.7/threading.pyc'

如何從import的語句從C++實現對a.print_name("John")? 任何幫助表示讚賞。

回答

5

我將稍微重寫Python類,只是它使用參數和成員變量。

# B.py - test module 
class A: 
    def __init__(self, name): 
     self.name = name 

    def print_message(self, message): 
     print message + ' ' + self.name 

至於C++的一部分,幾乎一切看起來都正常。你得到的錯誤是因爲參數PyInstance_New應該是一個元組。有多種方法可以調用函數或方法。以下是使用其中一個的完整示例:

// test.c - test embedding. 
void error_abort(void) 
{ 
    PyErr_Print(); 
    exit(EXIT_FAILURE); 
} 

int main(int argc, char* argv[]) 
{ 
    PyObject* temp, * args, * attr, * instance; 

    Py_Initialize(); 
    if (!(temp = PyString_FromString("John"))) 
     error_abort(); 
    if (!(args = PyTuple_Pack(1, temp))) 
     error_abort(); 
    Py_DECREF(temp); 

    if (!(temp = PyImport_ImportModule("B"))) 
     error_abort(); 
    if (!(attr = PyObject_GetAttrString(temp, "A"))) 
     error_abort(); 
    Py_DECREF(temp); 

    if (!(instance = PyInstance_New(attr, args, NULL))) 
     error_abort(); 
    if (!PyObject_CallMethod(instance, "print_message", "s", "Hello")) 
     error_abort(); 

    Py_DECREF(args); 
    Py_DECREF(attr); 
    Py_DECREF(instance); 
    Py_Finalize(); 
    return 0; 
} 

欲瞭解更多信息,請參閱Python pure-embedding

+0

非常棒!奇蹟般有效。 – pseudo

+0

真棒 - 感謝老兄! –