<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 23, 2014 at 2:59 PM, Amey Patil <span dir="ltr"><<a href="mailto:amey.patil@sjsu.edu" target="_blank">amey.patil@sjsu.edu</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Hi,<br>I am at the basic level in using sip wrapper in python. I have written a small library in c++ and wrapping it in sip for execution in Python.<br>

Copy pasting my entire files for better understanding. Also pasting
 the output from the terminal, the behaviour i am getting is completely unexpected, can you 
please look into it...<br></div></div></blockquote><div><br></div><div>I've included some options. As I do not know your overall skill level in C++/Python, I have included quite a bit of detail overall.</div><div><br>

</div><div>Without knowing your full use cases, in addition to sip, you may want to look at Cython (compiles a very Python-like language to C code), using the Python C APIs directly (a fairly direct replacement for sip), or using PyPy (which has a JIT compiler for Python to speed it up). Each of the four options has its own benefits and drawbacks.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><br>
</div><div><b>word.h:</b><br><span style="color:rgb(255,0,0)"><br><span style="color:rgb(102,102,102)">class Word<br>{<br><br>public:<br>    int integer;<br>    const char *name;<br>    Word();<br>    void set_name(const char *a);<br>



    void reset_name();<br>    const char *get_name();<br>};</span></span><span style="color:rgb(102,102,102)"><br></span><br></div><div><b>word.cpp:</b><br><span style="color:rgb(102,102,102)"><br>#include <iostream><br>



#include "word.h"<br><br>using namespace std;<br><br>Word::Word(){<br>    name = "PyQt";<div><br>}<br><br>void Word::set_name(const char *a){<br></div>    cout << "parameter passed to set_name is " << a << endl;<br>



    cout << "name before set_name is " << name << endl;<br>    name = a;<br></span></div></div></blockquote><div><br></div><div>This line is probably your problem. You'll probably want to copy the string "a" into a buffer rather than assign the pointer. Without this, as soon as the string pointed to by "a" is deallocated, the name parameter becomes invalid. This is known as a dangling pointer, and can cause odd bugs, such as getting random values or crashing when accessing.</div>

<div><br></div><div>For cases where a will be a constant, hard-coded, C variable (such as for reset_name below), the string will typically be held in a data section that will live for as long as the program runs, and thus it will work. If you were to call set_name from a value read from a file, however, you'd likely find the name will change later, similar to the sip-wrapped code.</div>

<div><br></div><div>There are a few common ways to deal with this in C:</div><div>1) Use a constant size char buffer, such as, in the class use "char name[32]" rather than "const char *name", then use strcpy to copy the new value into the fixed-size buffer. Be aware of the issues with copying more than the size of the buffer!</div>

<div>2) Use a dynamically allocated array: use the malloc function or new operator to make the name buffer based on the length of the string set, then do the strcpy as above. You have to be sure to properly free the memory when destroying the Word object or when new memory is allocated for name. You can also use a string class such as std::string (C++ standard library) which does this internally, with safety mechanisms.</div>

<div>3) Keep a reference to the Python string object. I do not know how to make sip do this (I haven't really used sip much). This will keep the memory valid, however you also have to be sure that when the reference is released when the name is changed again or the Word object is destroyed.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><span style="color:rgb(102,102,102)">    cout << "name after set_name is " << name << endl;<br>

}</span> </div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div> </div>

</div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><span style="color:rgb(102,102,102)">void Word::reset_name(){<br>



    cout << "name before reset_name is " << name << endl;<br>    const char *x = "Epics";<br>    name = x;</span></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><div><span style="color:rgb(102,102,102)">    cout << "name after reset_name is " << name << endl;<br>

}<br><br>const char *Word::get_name(){<br>    cout << "name before get_name is " << name << endl;<br>    return name;<br>}</span><br><br></div><div><b>word.sip:</b><br><span style="color:rgb(102,102,102)"><br>



%Module word <br><br>class Word<br>{<br><br>%TypeHeaderCode<br>#include <word.h><br>%End<br><br>public:<br>    int integer;<br>    const char *name;<br>    Word();<br>    void set_name(const char *a);<br>    void reset_name();<br>



    const char *get_name();<br>};</span><br><br></div><div><b>Output in Python (Terminal):</b><br><span style="color:rgb(255,0,0)"><br><span style="color:rgb(102,102,102)"><div>>>> import word<br>>>> w = word.Word()<br>


</div>
>>> w.get_name()<br>name before get_name is PyQt<br>'PyQt'<br>>>> w.set_name("Amey")<br>parameter passed to set_name is Amey<br>name before set_name is PyQt<br>name after set_name is Amey<br>

</span></span></div></div></blockquote><div><br></div><div>After the set_name call returns, the Python object "Amey" goes out of scope, and Python may garbage collect it. Often, this happens immediately, however for various reasons it could be kept around for a while. Try assigning "Amey" to a variable, then pass that variable into the function; the following code will probably work, until you replace or delete the variable, or the variable goes out of scope. Such an assignment will be similar to keeping a reference around in the C code (as mentioned above, I do not know how to do so with sip).</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><span style="color:rgb(255,0,0)"><span style="color:rgb(102,102,102)">

>>> w.get_name()<br><span style="background-color:rgb(255,255,0)">name before get_name is </span><br>''<br></span></span></div></div></blockquote><div><br></div><div>You've just read the memory that used to point to the string "Amey", but has been reused for other reasons. The new reason may change each time, and eventually the memory may be completely freed at the OS level, or used for a purpose for which you cannot read the memory, at which point you will get a crash.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><span style="color:rgb(255,0,0)"><span style="color:rgb(102,102,102)">>>> w.reset_name()<br>

<span style="background-color:rgb(255,255,0)">name before reset_name is <stdin></span><br>

name after reset_name is Epics<br>>>> w.get_name()<br>name before get_name is Epics<br>'Epics'</span></span><br><br></div><div>PROBLEMS:<br></div><div>1. It won't print the output when i call<span style="color:rgb(102,102,102)"> get_name()</span> after calling <span style="color:rgb(102,102,102)">set_name()</span>.<br>


2. As
 you can see in the output, I am editing nothing between the highlighted
 lines, still the output shows <span style="color:rgb(102,102,102)">nothing</span> in one while <span style="color:rgb(102,102,102)"><stdin></span> in 
other. <br><br>Please tell me what's wrong.<br>
<br></div><div>Looking forward for your reply,<br><br></div><div>Sincere Regards,<br></div>Amey Patil</div>
<br>_______________________________________________<br>
PyQt mailing list    <a href="mailto:PyQt@riverbankcomputing.com">PyQt@riverbankcomputing.com</a><br>
<a href="http://www.riverbankcomputing.com/mailman/listinfo/pyqt" target="_blank">http://www.riverbankcomputing.com/mailman/listinfo/pyqt</a><br></blockquote></div><br></div></div>