Hi,<div>I have been using Cython for a period of time.</div><div>But I can not find a description for the "api" key word in Cython documents </div><div><br></div><div><span style>cdef api float compute_norm(float init_value, float x, float y, float z):</span> </div>
<div><br><div><div><div>Can you explain it a little bit? Thanks!</div><div><br></div><div>Regards,</div><div>Liu Zhenhai</div><div><br></div><div><div class="gmail_quote">2012/1/10 Stefan Behnel <span dir="ltr"><<a href="mailto:stefan_ml@behnel.de">stefan_ml@behnel.de</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi again,<br>
<br>
just as a little teaser, to make it clear that I'm not joking, here's your<br>
code below translated into Cython.<br>
<br>
Stefan Behnel, 10.01.2012 13:33:<br>
> <a href="mailto:pasparis@noos.fr">pasparis@noos.fr</a>, 10.01.2012 11:57:<br>
<div class="im">>> the code is the following:<br>
</div>> [...]<br>
<div><div class="h5">>> // Class<br>
>> pclass = PyObject_GetAttrString(mymod, "cVector");<br>
>> if (pclass == NULL) {<br>
>> Py_DECREF(pclass);<br>
>> cout << "Can't find class\n";<br>
>> }<br>
>><br>
>> // Parameters/Values<br>
>> args = Py_BuildValue("(f)", 100.0);<br>
>> if (args == NULL) {<br>
>> Py_DECREF(args);<br>
>> cout << "Can't build argument list for class instance\n";<br>
>> }<br>
>><br>
>> // Object with parameter/value<br>
>> object = PyEval_CallObject(pclass, args);<br>
>> if (object == NULL) {<br>
>> Py_DECREF(object);<br>
>> cout << "Can't create object instance:\n";<br>
>> }<br>
>><br>
>> // Decrement the argument counter as we'll be using this again<br>
>> Py_DECREF(args);<br>
>><br>
>> // Get the object method - note we use the object as the object<br>
>> // from which we access the attribute by name, not the class<br>
>> method = PyObject_GetAttrString(object, "ComputeNorm");<br>
>> if (method == NULL) {<br>
>> Py_DECREF(method);<br>
>> cout << "Can't find method\n";<br>
>> }<br>
>><br>
>> // Decrement the counter for our object, since we now just need<br>
>> // the method reference<br>
>> Py_DECREF(object);<br>
>><br>
>> // Build our argument list - an empty tuple because there aren't<br>
>> // any arguments<br>
>><br>
>> cout << "Prepare the Tuple:\n" ;<br>
>> // WE pass a tuple<br>
>> args = PyTuple_New( 3 );<br>
>> if (args == NULL) {<br>
>> Py_DECREF(args);<br>
>> cout << "Can't build argument list for method call\n";<br>
>> }<br>
>><br>
>> PyObject *py_argument;<br>
>> // 1st argument<br>
>> py_argument = PyFloat_FromDouble(5.);<br>
>> PyTuple_SetItem(args, 0, py_argument);<br>
>><br>
>> // 2nd argument<br>
>> py_argument = PyFloat_FromDouble(10.);<br>
>> PyTuple_SetItem(args, 1, py_argument);<br>
>><br>
>> // 3nd argument<br>
>> py_argument = PyFloat_FromDouble(15.);<br>
>> PyTuple_SetItem(args, 2, py_argument);<br>
>><br>
>> cout << "Before the Exec:\n" ;<br>
>> // Call our object method with arguments<br>
>> //ret = PyEval_CallObject(method,args);<br>
>> ret = PyObject_CallObject(method,args);<br>
><br>
> Note that you are calling the method with three arguments here. It appears<br>
> that what you want is *one* argument instead, which happens to be a tuple.<br>
> So you need to wrap it in another tuple for calling. As I said, Cython will<br>
> do that for you.<br>
<br>
</div></div>And here's the Cython code:<br>
<br>
"""<br>
# in module "gluecode.pyx" (or whatever you want to name it)<br>
<br>
import mModule8<br>
<br>
cdef api float compute_norm(float init_value, float x, float y, float z):<br>
    vec = mModule8.cVector(init_value)<br>
    return vec.ComputeNorm( (x,y,z) )<br>
"""<br>
<br>
At least, that's what I read from your C code above. I'm assuming here that<br>
your program is using C or C++, and that you want to embed a CPython<br>
runtime in it and be able to execute Python code through it. The above<br>
"compute_norm()" function is exported (as a C function) by the "gluecode"<br>
module which you can import in your C/C++ code (as you did already).<br>
<br>
Note also that the Cython code above is substantially more efficient than<br>
your implementation, because it uses faster type conversions and interned<br>
Python names for looking up the class and its method.<br>
<span class="HOEnZb"><font color="#888888"><br>
Stefan<br>
<br>
--<br>
<a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
</font></span></blockquote></div><br></div></div></div></div>