4
#include <Python.h>

int
main (int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pValue;

    Py_Initialize ();

    pName = PyUnicode_FromString ("uuid");

    pModule = PyImport_Import (pName);
    Py_DECREF (pName);

    pFunc = PyObject_GetAttrString (pModule, "uuid4");

    pValue = PyObject_CallObject (pFunc, NULL);

    printf ("%s\n", PyUnicode_AsUTF8 (pValue));

    Py_Finalize ();

    return 0;
}

Compiled with

gcc test.c `python3.4-config --cflags --ldflags`

and I get Segmentation fault. How to fix this? What I want is getting the string back from uuid4(). Thank you.

dragosht
  • 3,237
  • 2
  • 23
  • 32
Henry Wong
  • 43
  • 3
  • I don't get a segfault. What version of gcc you are using? On which platform? – Anthony Kong Aug 22 '14 at 06:19
  • I got this: "TypeError: bad argument type for built-in operation". Very strange. I am using llvm gcc (Apple LLVM version 6.0 (clang-600.0.45.3)) on OSX 10.9.4 – Anthony Kong Aug 22 '14 at 06:39
  • Can you compile the program? – Henry Wong Aug 22 '14 at 06:50
  • Yes. Let me put the info in an answer. Comment is horrible for this – Anthony Kong Aug 22 '14 at 06:52
  • BTW, you need to provide more info as I mentioned before: what is the gcc version and platform. You can edit the question and put the info there – Anthony Kong Aug 22 '14 at 06:58
  • Arch Linux 64-bit. gcc 4.9.1. – Henry Wong Aug 22 '14 at 07:03
  • OK. See my answer for a suggested solution – Anthony Kong Aug 22 '14 at 07:07
  • @AnthonyKong Cound you also try this? With the same compile method. Do you have any error? `#include int main (int argc, char *argv[]) { PyObject *pModule; PyObject *pValue; Py_Initialize (); pModule = PyImport_AddModule ("__main__"); PyRun_SimpleString ("x = \"hello world\""); pValue = PyObject_GetAttrString (pModule, "x"); printf ("%s\n", PyUnicode_AsUTF8 (pValue)); Py_Finalize (); return 0; }` – Henry Wong Aug 22 '14 at 07:09
  • May be I am one step behind, I just found out this works too. `#include int main (int argc, char *argv[]) { PyObject *pModule; PyObject *pValue; Py_Initialize (); pModule = PyImport_AddModule ("__main__"); PyRun_SimpleString ("import uuid; x = str(uuid.uuid4())"); pValue = PyObject_GetAttrString (pModule, "x"); printf ("%s\n", PyUnicode_AsUTF8 (pValue)); Py_Finalize (); return 0; }` – Henry Wong Aug 22 '14 at 07:24

2 Answers2

0

I can successfully get it to compile and print out the value with some modifcation:

#include <Python.h>
#include <stdio.h>

int
main (int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pValue;

    Py_Initialize ();

    pName = PyUnicode_FromString ("uuid");

    pModule = PyImport_Import (pName);
    Py_DECREF (pName);

    pFunc = PyObject_GetAttrString (pModule, "uuid4");

    pValue = PyObject_CallObject (pFunc, NULL);

    PyObject_Print(pValue, stdout, Py_PRINT_RAW); // my change
    printf ("\n"); // make the printout look nicer

    Py_Finalize ();

    return 0;
}

And here is the output:

$ ./a.out
bd94cb52-9278-41a8-bc5a-ad05eff91188

I think the cause of your problem is most likely this: The compiler that compiled python is not the same as the one you used to compile your test program test.c. You can either find out the right version of gcc to compile your code, or simply recompile python3.4 with your current gcc compiler.

As for your original version of test.c, it gives this error on my MBP:

$ ./a.out
(null)
Exception ignored in: <module 'threading' from '/usr/local/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py'>
Traceback (most recent call last):
  File "/usr/local/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 1292, in _shutdown
    t = _pickSomeNonDaemonThread()
  File "/usr/local/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 1299, in _pickSomeNonDaemonThread
    for t in enumerate():
  File "/usr/local/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 1269, in enumerate
    return list(_active.values()) + list(_limbo.values())
TypeError: bad argument type for built-in operation

I don't really know what is going on.

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • This version works, but I want to found out the reason behind... See my Hello world in the comments above, it works for me so my first piece of code should works, but it didn't. – Henry Wong Aug 22 '14 at 07:20
0

I got a Fatal Python error: XXX block stack underflow using PyUnicode_AsUTF8. The trick for me was that the function allocates memory with the Python API, and therefore MUST be freed with PyMem_Free() from cpython.mem.

malloc() goes with free() as do PyMem_Malloc() goes with PyMem_Free()

Sylvain
  • 679
  • 9
  • 13