首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以使用哪些方法将struct返回给Python调用共享对象中的函数?

我可以使用哪些方法将struct返回给Python调用共享对象中的函数?
EN

Stack Overflow用户
提问于 2014-03-06 10:39:27
回答 2查看 805关注 0票数 1

我有下面的C文件,我正在编译成一个共享对象。然后,通过python中的ctype加载.so共享对象。我可以从ctype调用函数,函数输出正确的温度和湿度,但是我似乎无法从主代码中获得结构。如何从C函数中取回结构,以及如何从python中检索字段。

代码语言:javascript
复制
#!/bin/python

from ctypes import *
class HMTEMP(Structure):
 _fields_ = [ ("temp", c_double) , ("humidity", c_double) ]
dhtlib = 'libdht4py.so'
hlibc = CDLL(dhtlib)
HMTEMP = hlibc.readDHT()
print HMTEMP.temp
代码语言:javascript
复制
#define BCM2708_PERI_BASE        0x20000000
#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <bcm2835.h>
#include <unistd.h>

#define MAXTIMINGS 100

struct DHStruct {    
 double temp;
 double humidity;
}  ;


struct DHStruct readDHT();


int bits[250], data[100];
int bitidx = 0;

struct DHStruct readDHT() {
  bcm2835_init() ; 
  int type = 11 ; 
  int pin = 4 ;
  struct DHStruct dhts;
  int counter = 0;
  int laststate = HIGH;
  int j=0;

  // Set GPIO pin to output
  bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);

  bcm2835_gpio_write(pin, HIGH);
  usleep(500000);  // 500 ms
  bcm2835_gpio_write(pin, LOW);
  usleep(20000);

  bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);

  data[0] = data[1] = data[2] = data[3] = data[4] = 0;

  // wait for pin to drop?
  while (bcm2835_gpio_lev(pin) == 1) {
    usleep(1);
  } //while

  // read data!
  for (int i=0; i< MAXTIMINGS; i++) {
    counter = 0;
    while ( bcm2835_gpio_lev(pin) == laststate) {
    counter++;
    //nanosleep(1);     // overclocking might change this?
        if (counter == 1000)
      break;
    }//while
    laststate = bcm2835_gpio_lev(pin);
    if (counter == 1000) break;
    bits[bitidx++] = counter;

    if ((i>3) && (i%2 == 0)) {
      // shove each bit into the storage bytes
      data[j/8] <<= 1;
      if (counter > 200)
        data[j/8] |= 1;
      j++;
    }//if
  } //for

    dhts.temp = data[2] ;
    dhts.humidity = data[0] ; 
    printf("Temp = %5.2f *C, Hum = %5.2f \%\n", dhts.temp , dhts.humidity );

  return dhts;
}//function
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-09 06:05:33

好的,我明白了--而且使用ctype非常快。python代码:

代码语言:javascript
复制
#!/bin/python
from ctypes import *
# define the struct and it's fields
class DHStruct(Structure):
    _fields_ = [("temp",c_double),("humidity",c_double)]
#reference the library
dhtlib = CDLL("libdht4py.so")
# set the return type as the object above 
dhtlib.readDHT.restype = POINTER(DHStruct)
# dereference the pointer using ctype's -contents and access the struct fields.
print ( dhtlib.readDHT().contents.temp ,   dhtlib.readDHT().contents.humidity  )

C代码:关键是将函数转换为返回指针。

代码语言:javascript
复制
    #define BCM2708_PERI_BASE        0x20000000
    #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <fcntl.h>
    #include <assert.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/time.h>
    #include <bcm2835.h>
    #include <unistd.h>

    #define MAXTIMINGS 100

//define the struct
    struct DHStruct {
     double temp;
     double humidity;
    }  ;


    struct DHStruct *readDHT(); // define the function prototype to return the pointer


    int bits[250], data[100];
    int bitidx = 0;

    //make sure to return a POINTER!!
    struct DHStruct *readDHT() {
      bcm2835_init() ;
      int type = 11 ;
      int pin = 4 ;
      struct DHStruct *dhts; // here is the key - define the pointer to the struct
      int counter = 0;
      int laststate = HIGH;
      int j=0;

      // Set GPIO pin to output
      bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);

      bcm2835_gpio_write(pin, HIGH);
      usleep(500000);  // 500 ms
      bcm2835_gpio_write(pin, LOW);
      usleep(20000);

      bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);

      data[0] = data[1] = data[2] = data[3] = data[4] = 0;

      // wait for pin to drop?
      while (bcm2835_gpio_lev(pin) == 1) {
        usleep(1);
      } //while

      // read data!
      for (int i=0; i< MAXTIMINGS; i++) {
        counter = 0;
        while ( bcm2835_gpio_lev(pin) == laststate) {
            counter++;
            //nanosleep(1);         // overclocking might change this?
            if (counter == 1000)
              break;
        }//while
        laststate = bcm2835_gpio_lev(pin);
        if (counter == 1000) break;
        bits[bitidx++] = counter;

        if ((i>3) && (i%2 == 0)) {
          // shove each bit into the storage bytes
          data[j/8] <<= 1;
          if (counter > 200)
            data[j/8] |= 1;
          j++;
        }//if
      } //for

            dhts->temp = data[2] ;
            dhts->humidity = data[0] ;
   //for debug  printf("Temp = %5.2f *C, Hum = %5.2f \%\n", dhts->temp , dhts->humidity );

      return dhts;
    }//function
票数 1
EN

Stack Overflow用户

发布于 2014-03-07 16:54:43

要将C/C++和Python结合起来,我建议使用Cython。使用Cython,您可以传递对象(例如。( numpy数组)到C/C++,用您的数据填充它并将其返回到您的python代码。

下面是一个简单的例子:

C:(c_example.c)

代码语言:javascript
复制
#include <stdlib.h>
#include <math.h>

void c_claculate(double *x, int N) {
  int i;
  for (i = 0; i<N;i++) {
    x[i]+=i*i;
  }
}

python:(example.py)

代码语言:javascript
复制
from numpy import *
from example import *

data=zeros(10)
calculate(data)
print data

.pyx文件:(example.pyx)

代码语言:javascript
复制
import cython
import numpy
cimport numpy

# declare the interface to the C code
cdef extern void c_claculate(double *x, int N)

# Cython interface to C function
def calculate(numpy.ndarray[double, ndim=1, mode='c'] x not None):
    cdef int N = x.shape[0]
    c_claculate(&x[0],N)
    return x

和安装文件:(setup.py)

代码语言:javascript
复制
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy

setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [
        Extension("example",
                  sources=["example.pyx", "c_example.c"],
                  include_dirs=[numpy.get_include()]
                  )
    ],
)

现在可以通过运行skript编译skript。

代码语言:javascript
复制
python setup.py build_ext -fi

然后执行python skript。

Cython应该可以通过PI上的pip获得。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22443781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档