简体   繁体   中英

I can create my C++ object in Python, but can't access methods

Sorry, there's a lot here, but I really think all of this information is relevant to the question I'm about to ask.

So I wrapped my C++ class using SWIG, compiled, etc. and in a python script I create an instance of my class and then try to call a method on that class. Notice I said "try" to call. The call on the method fails. Details on implementation & "fails" follows.

First, I am building the Python3.4 interpreter with my Windows application and calling my python script as follows:

Py_Initialize();

/* Some code here to set up python paths. */
.....

PyObject *pName = PyUnicode_FromString("hello");
if(pName == NULL)
{
    Py_Finalize();
    return false;
}

PyObject* pModule = PyImport_Import(pName);
if(pModule == NULL)
{
    Py_Finalize();
    return false;
}

/* "go" is the name of the function in my python script that I want to call. */
PyObject *pFunc = PyObject_GetAttrString(pModule, "go");
if(pFunc == NULL)
{
    Py_Finalize();
    return false;
}

PyObject *pArgs = PyTuple_New(0);
PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
if(pValue == NULL)
{
    Py_Finalize();
    return false;
}

Py_Finalize();
return true;

===================

Here's my class structure:

class BoganDocument
{
private:
    BoganMetadataSet    myMetadata;

public:
    // Constructor
    BoganDocument();

    // Destructor
    virtual ~BoganDocument();

    // Useful methods.
    wstring     getMetadataValue(wstring metadata_name);
}

===================

Here's my Python script (named "hello.py").

import BoganDocument
def go():
    print("I'm in go()")
    d = BoganDocument.BoganDocument()
    print("I made a document")
    ts = d.getMetadataValue("CreationTimestamp");
    print("The creation timestamp is " + ts)

=====================

And the output on my console screen looks like this:

trying C:\Program Files (x86)\MyApp\Python\swig_runtime_data4_d.pyd
trying C:\Program Files (x86)\MyApp\Python\swig_runtime_data4.py
trying C:\Program Files (x86)\MyApp\Python\swig_runtime_data4.pyw
trying C:\Program Files (x86)\MyApp\Python\swig_runtime_data4.pyc
trying c:\MyApp\Workplace\swig_runtime_data4_d.pyd
trying c:\MyApp\Workplace\swig_runtime_data4.py
trying c:\MyApp\Workplace\swig_runtime_data4.pyw
trying c:\MyApp\Workplace\swig_runtime_data4.pyc
import 'BoganDocument' # <_frozen_importlib.SourceFileLoader object at 0x10D2E3F0>
import 'hello' # <_frozen_importlib.SourceFileLoader object at 0x10D2E1C0>
I'm in go()
I made a document

===================

Notice that I have set PYTHONVERBOSE to 11 to get as much diagnostic information as I can. And notice that all messages stop after "print("I made a document")". No syntax error, nothing. The value of pValue after "PyObject *pValue = PyObject_CallObject(pFunc, pArgs);" is NULL.

Now, the call to the constructor at "d = BoganDocument.BoganDocument()" is known to work, as I've set a breakpoint in the BoganDocument constructor and single stepped through.

I also set a breakbpoint in BoganDocument's getMetadataValue method but never get there. And there's the mystery.

No doubt I have a bug, but I haven't a clue.

Did you step into the SWIG wrapper for getMetadataValue ? The C++ wrapper gets called when you do d.getMetadataValue() frm Python, the C++ wrapper then calls Bogan::getMetadataValue on the appropriate C++ instance. Since you never get to the C++ instance's getMetadataValue , maybe SWIG wrapper is finding the call to be illegal or such (SWIG doesn't normally silently ignore problems but I don't know what else to suggest). Since you are using wide string, make sure you include std_wstring.i .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM