【问题标题】:Python Ctypes Passing in Pointer and Getting Struct BackPython Ctypes 传入指针并返回结构
【发布时间】:2012-05-16 03:11:22
【问题描述】:

这是我在解决实际有用的问题之前尝试开始工作的一个简单示例。 C代码:

typedef struct {
  uint32_t seconds;
  uint32_t nanoseconds;
} geoTime;

int myTest(geoTime *myTime){
  printf("Time: %d %d\n", myTime->seconds, myTime->nanoseconds);
  myTime->seconds = myTime->nanoseconds;
  geoTime T = {314, 159};
  printf("MyTime: %d %d      retValue: %d %d\n", myTime->seconds, myTime->nanoseconds, T.seconds, T.nanoseconds);
  return 314;
}

Python 代码:

import ctypes
import time
import math

lib_astro = ctypes.CDLL("libastroC.so")

class geoTime(ctypes.Structure):
    _fields_ = [("seconds", ctypes.c_uint),
                ("nanoseconds", ctypes.c_uint)]  

now = time.time()
print "Python Now: ", now

now_geoTime = geoTime()
now_geoTime.seconds = ctypes.c_uint(int((math.floor(now))))
now_geoTime.nanoseconds = ctypes.c_uint(int(math.floor(math.modf(now)[0] * 1000000000)))
print "Python geoTime now:", now_geoTime.seconds, now_geoTime.nanoseconds

lib_astro.myTest.argtypes = [ctypes.POINTER(geoTime)]
lib_astro.myTest.restype = geoTime
print "************* ENTERING C ********************"
test = lib_astro.myTest(ctypes.byref(now_geoTime))
print "************* EXITING C **********************"
print "Modified now_geoTime: ",now_geoTime.seconds, now_geoTime.nanoseconds
print "test: ",test

输出:

Python Now:  1336401085.43
Python geoTime now: 1336401085 432585000
************* ENTERING C ********************
Time: 1336401085 432585000
MyTime: 432585000 432585000      retValue: 314 159
************* EXITING C **********************
Modified now_geoTime:  432585000 432585000
test:  314

上面的代码完全符合我的预期,我的指针进入并被修改,我得到了我的整数。当我尝试在 C 中创建 geoTime 结构并将其返回给 Python 时,就会出现问题。

在 C 中添加/修改代码:

geoTime patTest(geoTime *myTime){
    printf("Time: %d %d\n", myTime->seconds, myTime->nanoseconds);
    myTime->seconds = myTime->nanoseconds;
    geoTime T = {314, 159};
    printf("MyTime: %d %d      retValue: %d %d\n", myTime->seconds, myTime->nanoseconds, T.seconds, T.nanoseconds);
    return T;

}

修改后的 Python 代码:

lib_astro.patTest.argtypes = [ctypes.POINTER(geoTime)]
lib_astro.patTest.restype = geoTime
print "************* ENTERING C ********************"
test = lib_astro.patTest(ctypes.byref(now_geoTime))
print "************* EXITING C **********************"
print "Modified now_geoTime: ",now_geoTime.seconds, now_geoTime.nanoseconds
print "Type of test: ",test
print "Information in test: ", test.seconds, test.nanoseconds

一旦我像这样更改我的代码,C 代码就会进入 myTime 而不是来自 Python 的信息,并且返回值会被放入 now_geoTime 而不是 test。关于可能出现问题的任何想法?看起来 python 代码没有按照我期望的方式做某事,因为 C 代码似乎可以正确处理传入的值。

最后一个例子的输出:

Python Now:  1336404920.77
Python geoTime now: 1336404920 773674011
************* ENTERING C ********************
Time: 90500 -17037640
MyTime: -17037640 -17037640      retValue: 314 159
************* EXITING C **********************
Modified now_geoTime:  314 159
Type of test:  <__main__.geoTime object at 0x82bedf4>
Information in test:  137096800 134497384

任何想法都将不胜感激,我一直在努力让它工作很长一段时间。提前致谢!

【问题讨论】:

  • 我试了一下你的代码,和你的完全一样。我得到了您正在寻找的正确输出。所以我只能说我相信你的代码是正确的;可能是编译器或平台问题。
  • 好的,谢谢。经过一番挖掘,我发现由于某种原因从我编译的库中返回结构是行不通的。现在我将假设对于我需要返回结构的少数方法,我将在 C 端包装它以从堆中分配一些内存并返回一个带有结构副本的指针。我可能会尝试查看用于返回结构的编译器选项,看看那里是否有我注意到的任何东西。如果其他人有一些想法,我愿意接受他们

标签: python c pointers struct ctypes


【解决方案1】:

我切换到 64 位 python/64 位 dll,问题就消失了。当我感觉更有灵感时,我可能会尝试将其隔离到编译器、操作系统或 python,但现在我将使用它运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多