简体   繁体   English

有没有办法在Python和C之间传递结构

[英]Is there a way to pass structure between Python and C

I am writing a program in C using Python API. 我正在使用Python API用C编写程序。

Python will pass the input(structure) to C program and C program will perform some operations based on the input. Python将把输入(结构)传递给C程序,而C程序将根据输入执行一些操作。

Could anyone please tell me is it possible to pass structure between Python and C. If yes kindly let me know how to pass it. 谁能告诉我是否可以在Python和C之间传递结构。如果可以,请让我知道如何传递它。

I have used SWIG interface to pass values between C and Python. 我已经使用SWIG接口在C和Python之间传递值。 Sample program is working fine (Using variables). 示例程序运行正常(使用变量)。 I have added code with structure, but i am not sure about the code format for that. 我已经添加了具有结构的代码,但是我不确定该代码的格式。 Please correct me if i am doing anything wrong. 如果我做错了什么,请纠正我。 I am completely new to Python and C. I searched everywhere for passing structure using SWIG, i couldn't get any correct answer. 我对Python和C完全陌生。我到处搜索了使用SWIG传递结构的信息,但无法获得正确的答案。

Logic is to fetch the input values from Python and perform the multiplication operation in c and return the values to Python. 逻辑是从Python获取输入值并在c中执行乘法运算,然后将值返回给Python。

Sample.c
#include<stdio.h>
#include "sample.h"

struct info sample;

int getstruct (struct info sample);

int getstruct (struct info sample) {

   int i = 0;
   int j = 0;
   int k = 0;
   int l = 0;

   i = 2 * sample.i;
   j = 2 * sample.j;
   k = 2 * sample.k;
   l = 2 * sample.l;

   sample.i = i;
   sample.j = j;
   sample.k = k;
   sample.l = l;

   return(&sample);

}

sample.h
struct info
{
   int i;
   int j;
   int k;
   int l;
};

extern struct info data;

sample.i
%module sample
%{
#include "sample.h"
%}

%include "sample.h"

sample.py (automatically generated by SWIG)
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 2.0.11
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.





from sys import version_info
if version_info >= (2,6,0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_sample', [dirname(__file__)])
        except ImportError:
            import _sample
            return _sample
        if fp is not None:
            try:
                _mod = imp.load_module('_sample', fp, pathname, description)
            finally:
                fp.close()
            return _mod
    _sample = swig_import_helper()
    del swig_import_helper
else:
    import _sample
del version_info
try:
    _swig_property = property
except NameError:
    pass # Python < 2.2 doesn't have 'property'.
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
    if (name == "thisown"): return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name,None)
    if method: return method(self,value)
    if (not static):
        self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)

def _swig_setattr(self,class_type,name,value):
    return _swig_setattr_nondynamic(self,class_type,name,value,0)

def _swig_getattr(self,class_type,name):
    if (name == "thisown"): return self.this.own()
    method = class_type.__swig_getmethods__.get(name,None)
    if method: return method(self)
    raise AttributeError(name)

def _swig_repr(self):
    try: strthis = "proxy of " + self.this.__repr__()
    except: strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

try:
    _object = object
    _newclass = 1
except AttributeError:
    class _object : pass
    _newclass = 0


class info(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, info, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, info, name)
    __repr__ = _swig_repr
    __swig_setmethods__["i"] = _sample.info_i_set
    __swig_getmethods__["i"] = _sample.info_i_get
    if _newclass:i = _swig_property(_sample.info_i_get, _sample.info_i_set)
    __swig_setmethods__["j"] = _sample.info_j_set
    __swig_getmethods__["j"] = _sample.info_j_get
    if _newclass:j = _swig_property(_sample.info_j_get, _sample.info_j_set)
    __swig_setmethods__["k"] = _sample.info_k_set
    __swig_getmethods__["k"] = _sample.info_k_get
    if _newclass:k = _swig_property(_sample.info_k_get, _sample.info_k_set)
    __swig_setmethods__["l"] = _sample.info_l_set
    __swig_getmethods__["l"] = _sample.info_l_get
    if _newclass:l = _swig_property(_sample.info_l_get, _sample.info_l_set)
    def __init__(self):
        this = _sample.new_info()
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _sample.delete_info
    __del__ = lambda self : None;
info_swigregister = _sample.info_swigregister
info_swigregister(info)

# This file is compatible with both classic and new-style classes.

cvar = _sample.cvar


Error message:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sample
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sample.py", line 28, in <module>
    _sample = swig_import_helper()
  File "sample.py", line 24, in swig_import_helper
    _mod = imp.load_module('_sample', fp, pathname, description)
ImportError: ./_sample.so: undefined symbol: data
>>>

Commands used:
swig -python sample.i
gcc -fPIC -c sample.c sample_wrap.c -I/usr/include/python2.7
ld -shared sample.o sample_wrap.o -o _sample.so

You can check out swig . 你可以看看swig

I use it myself and can confirm that it works quite well. 我自己使用它,可以确认它运行良好。 Check out the tutorial for a python example. 查看该教程以获取python示例。

The following code is executing: 正在执行以下代码:

Header file: 头文件:

#include<stdio.h>

typedef struct
{
   int i;
   int j;
   int k;
   int l;
} MyStruct;

extern MyStruct sample;

extern int getstruct (MyStruct sample);

C file C档

#include "example.h"

int getstruct (MyStruct sample) {

   int i = 0;
   int j = 0;
   int k = 0;
   int l = 0;

   i = 2 * sample.i;
   j = 2 * sample.j;
   k = 2 * sample.k;
   l = 2 * sample.l;

   sample.i = i;
   sample.j = j;
   sample.k = k;
   sample.l = l;

   return(&sample);
}

Interface file: 接口文件:

%module example
%{
#include "example.h"
%}

%include "example.h"

Compile and link files: 编译和链接文件:

$ swig -python example.i
$ gcc -fPIC -c example.c example_wrap.c -I/usr/include/python2.7
$ gcc -lpython -shared example.o example_wrap.o -o _example.so

Now to python: 现在到python:

>>> import example
>>> a = example.MyStruct
>>> dir(a)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', 
 '__format__', '__getattr__', '__getattribute__', '__hash__',
 '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
 '__repr__', '__setattr__', '__sizeof__', '__str__',
 '__subclasshook__', '__swig_destroy__', '__swig_getmethods__',
 '__swig_setmethods__', '__weakref__', 'i', 'j', 'k', 'l', 'this']
>>> a.i = 1
>>> a.j = 1
>>> a.k = 1
>>> a.l = 1
>>> example.getstruct(a)
1605330080

I am not sure what the result is (the address of sample maybe?). 我不确定结果是什么(可能是示例的地址?)。

PS :I had a look at the reply from Lee Daniel Crocker , it deserves consideration. PS :我看了李·丹尼尔·克罗克Lee Daniel Crocker)的回复,值得考虑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM