3

I've initialized the Python environment by

Py_Initialize();

I have no external Python module imported into the environment and everything works well. But when I need to pass a C string into this environment, I am lost...

I was thinking to add a function in the environment to assign the variable like the following code do.

char *str;
str="\
def assign_var(str):\
    global string\
    string = str";
PyRun_SimpleString(str);

And then call this function in C and pass the converted C string as the arguments.

I don't think all I mentioned above is a good way solve the problem...

How can I make this work?

Solution:

Finally, here's the solution with Peter Mortensen's help. (Thanks Peter Mortensen!)

As the python environment I've initialized is a pure empty environment(without any imported modules). I use

py_main = PyImport_AddModule("__main__");

to get a hook to the main environment. and then call

PyModule_AddStringConstant(py_main, "string_name", str);

to bring the C string into the python environment.

To verify everything is done, just try:

PyRun_SimpleString("print dir()");
PyRun_SimpleString("print string_name");

and you'll see you "string_name" string appears in the dir() list and make it print by python!

Community
  • 1
  • 1
alwinlin
  • 703
  • 1
  • 5
  • 21
  • Perhaps a variation on [this](http://stackoverflow.com/q/3001239/577088) would work? – senderle Jun 08 '11 at 16:34
  • @senderle sorry, [that case](http://stackoverflow.com/questions/3001239/define-global-in-a-python-module-from-c-api), he already has a variable g in the module, but in my case I've none... thanks to your comment, I've reprecised the title of my question(added 'creat') – alwinlin Jun 08 '11 at 16:45
  • my thought was that you might be able to acquire a reference to `__main__` using [`PySys_GetObject`](http://docs.python.org/c-api/sys.html#PySys_GetObject). But without knowing exactly what you're doing it's a bit hard to tell what you want to happen. – senderle Jun 09 '11 at 03:56

1 Answers1

2

This should do what you want:

char *cStr = "Some text here.";

PyObject *pyStr = Py_BuildValue("s", cStr);

http://docs.python.org/c-api/arg.html#Py_BuildValue

Of course if you're using Python 3 (or use it in the future), there may be situations where you'd want to use "y" instead of "s" and get a bytes object rather than a str.

UPDATE: Woops, I forgot the even easier way of doing it.

PyObject *pyStr = PyString_FromString(cStr);

http://docs.python.org/c-api/string.html#PyString_FromString

(It'd be PyBytes_FromString() in Python 3.)

You might want to take a look at http://docs.python.org/extending/embedding.html for some more information.


Here's something else you might want to try. See

http://docs.python.org/c-api/module.html#PyModule_AddObject
Or possibly
http://docs.python.org/c-api/module.html#PyModule_AddStringConstant

With the former it'd be something like

errorcheck = PyModule_AddObject(embmodule, "str", pyStr);

And with the latter, something like

errorcheck = PyModule_AddStringConstant(embmodule, "str", cStr);
JAB
  • 20,783
  • 6
  • 71
  • 80
  • sorry, this is not what I'm looking for... all the functions you mentioned here return always PyObject* and nothing happens in the python environment. The python string stays still in C environment not in the python one. Do you have any idea about transfering the python string into python environment from the C one? – alwinlin Jun 08 '11 at 20:22
  • Look at http://docs.python.org/extending/embedding.html#extending-embedded-python. You'll need to write a function that returns the string as a PyObject using the same `PyString_FromString()` function I showed, make an array of PyMethodDef objects, and then initialize a module with that array of methods. You'd then import your module from the Python side and call the methods of the module to access the data. – JAB Jun 08 '11 at 20:32
  • `PyMethodDef` structs, rather. – JAB Jun 08 '11 at 20:55
  • Hi, sorry for my late response. I've finally found a way to creat and assign a string. As you mentioned, I'm using Module_AddStringConstant(mod, "name", cStr); – alwinlin Jun 09 '11 at 09:50