我无法使用swing模块将字典从python解析为C程序。我编写了一个wrapper_dict.c和struct.c程序。
wrapper.c
#include <Python.h>
#include "struct.h"
PyObject *dictionary(PyObject *self, PyObject *args) {
PyObject *dict;
int result;
if (!PyArg_ParseTuple(args, "O", &dict))
return NULL;
result = printBook(&dict);
return Py_BuildValue("i", result);
}
static PyMethodDef dictMethods[] = {
{ "printBook", dictionary, 1 },
{ NULL, NULL }
};
void initdict() {
PyObject *m;
m = Py_InitModule("dict", dictMethods);
}
Struct.c:
#include<stdio.h>
#include<string.h>
#include "struct.h"
int printBook (struct Books *book) {
printf(" Book title: %s\n", book->title);
printf(" Book author: %s\n", book->author);
printf(" Book subject: %s\n", book->subject);
printf(" Book book_id: %d\n", book->book_id);
return 1;
}
使用动态加载:
xyz@M:~/Python/Cprogam/work$ gcc -fpic -c $(pkg-config --cflags --libs python2) wrapper_dict.c struct.c
xyz@M:~/Python/Cprogam/work$ gcc -shared wrapper_dict.o struct.o -o dictmod.so
当我将字典传递给printBook时,我看到printf语句返回一堆垃圾值。
xyz@M:~/Python/Cprogam/work$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:38)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dict
>>> books= { 'title':'C progamming', 'author' : 'J k', 'subject' : 'telecomm', 'book_id': '345524'}
>>>
>>> dict.printBook(books)
Book title: t?"?/0l?
Book author: s?D
Book subject:
Book book_id: 4
1
我错过了什么吗?请告诉我。提前致谢。
答案 0 :(得分:1)
您必须将Python对象转换为正确的C结构。
这是一个有效的例子。错误检查是为了简洁而遗漏,我猜到了struct.h
。我还使用Python 3.3 x64并使用Python的调试版本构建来检查引用计数:
#include <Python.h>
#include "struct.h"
PyObject *wrap_printBook(PyObject *self, PyObject *args)
{
PyObject *dict,*py_subject,*py_title,*py_author,*py_book_id;
struct Books book;
int result;
// Parse the Python function arguments. Expect one object.
if (!PyArg_ParseTuple(args, "O", &dict))
return NULL;
// Expect a Python dictionary, retrieve the expected string values.
// Note PyDict_GetItemString returns a borrowed reference. Don't DECREF it.
py_subject = PyDict_GetItemString(dict,"subject");
py_title = PyDict_GetItemString(dict,"title");
py_author = PyDict_GetItemString(dict,"author");
py_book_id = PyDict_GetItemString(dict,"book_id");
// Copy the strings into the C structure.
// Unsafe copy, I know. I'm not doing all the work :)
strcpy(book.subject,PyUnicode_AsUTF8(py_subject));
strcpy(book.author,PyUnicode_AsUTF8(py_author));
strcpy(book.title,PyUnicode_AsUTF8(py_title));
// I made book_id an int, so convert the PyUnicode string to a PyInt, then an int.
py_book_id = PyLong_FromUnicodeObject(py_book_id,10); // convert to PyLong (new ref!)
book.book_id = PyLong_AsLong(py_book_id);
Py_DECREF(py_book_id); // release ref
// Now that the PyDict has been converted to a C value, call the function.
result = printBook(&book);
return Py_BuildValue("i", result);
}
static PyMethodDef bookMethods[] = {
{"printBook", wrap_printBook, METH_VARARGS, "Call printBook."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef bookModule = {
PyModuleDef_HEAD_INIT, "book", NULL, -1, bookMethods
};
PyMODINIT_FUNC PyInit_book(void) {
return PyModule_Create(&bookModule);
}
#define MAX_STRING 80
struct Books
{
char title[MAX_STRING];
char author[MAX_STRING];
char subject[MAX_STRING];
int book_id;
};
int printBook (struct Books *book);
Python 3.3.2 (VS110.diff:bca965c8a064+, Jun 1 2013, 13:52:13) [MSC v.1700 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import book
[64847 refs]
>>> book.printBook({'subject':'subject1','title':'title1','author':'author1','book_id':'123456'})
Book title: title1
Book author: author1
Book subject: subject1
Book book_id: 123456
1
[64852 refs]
>>> book.printBook({'subject':'subject1','title':'title1','author':'author1','book_id':'123456'})
Book title: title1
Book author: author1
Book subject: subject1
Book book_id: 123456
1
[64852 refs] # multiple calls, no reference leaks!