【问题标题】:casting ctypes c_void_p to C output parameter将 ctypes c_void_p 转换为 C 输出参数
【发布时间】:2018-12-24 22:29:36
【问题描述】:

首先我知道Python ctypes, pass c_void_p as an out parameter to c function 和他们建议的解决方案,但我无法通过他们的回答使其工作。反正我的问题是类似的...

我有一个 C 函数,我想使用 ctypes 用 Python 进行包装。它接受

error_t foo(int a,void ** bar)

以bar 作为输出参数。

我的 Python ctypes 看起来像链接线程中描述的那样:

bar = c_void_p()
foo(guids, byref(bar))

我不知道我做错了什么或有什么不同......我有点无能为力......

bar 类型的输出总是只显示:

c_void_p(None)

感谢任何帮助或想法...

【问题讨论】:

  • 建议使用 cffi 代替 ctypes。它提供了一个更简单的界面。所以如果你没有绑定ctypes,看看:cffi.readthedocs.io/en/latest/…
  • 您期望的输出是什么?在链接的问题中,正确答案打印指针的属性(contents);这对你的目标有影响吗?
  • 我希望它有一个值,更具体的识别句柄......我编辑了问题以使其更清楚。 @jackw11111 会看一看,坦克。@Joe

标签: python c++ python-3.x ctypes out


【解决方案1】:

以下内容:

import os
file=open("/tmp/1.c","w")
# you didn't provide the implementation of foo (why?) so i needed to write it myself
file.write(
"typedef int error_t;"
"error_t foo(int a,void ** bar) {"
"       *bar = a;"
"       return a * 2;"
"}"
)
file.close()
os.system("gcc -Wno-int-conversion -shared -o /tmp/lib1.so.1 /tmp/1.c")

import ctypes
lib1 = ctypes.cdll.LoadLibrary("/tmp/lib1.so.1")
guids = 1000

# the code you provided us
bar = ctypes.c_void_p()
ret = lib1.foo(guids, ctypes.byref(bar))
# end of the code you provided us

print("foo(" + str(guids) + ", " + str(ctypes.byref(bar)) + ") = " + str(ret))
print("And bar has the value: " +  str(bar));

打印出来:

foo(1000, <cparam 'P' (0x7ffa3414ee68)>) = 2000
And bar has the value: c_void_p(1000)

脚本将一个简单的 C 程序编译成一个共享库:

typedef int error_t;
error_t foo(int a,void ** bar) {
       *bar = a;
       return a * 2;
}

然后使用 python 中的 ctypes 运行该函数。
正如预期的那样,调用foo(1000, ...) 返回2000 并将void *bar 的值设置为1000。所以你做的python调用没问题,检查函数。可能您的foo() 设置的值是bar 到NULL。

【讨论】:

  • 首先感谢您的详细回答!我没有提供 foo 的代码,因为它是 .so/.dll 的一部分,我只能访问头文件。无论如何,我不得不说这个函数似乎工作得很好,因为来自 C++ 的调用以及来自我们的 C# Wrapper 的调用确实工作得很好......来自 C# Wrapper 的 sn-p:IntPtr handle= IntPtr.Zero; string guid = guidList[1]; errorCode = OpenCamera(guid, out handle);@Kamil Cuk
  • 在我同事的帮助下修复了它 :) 但你是对的,问题出在 .dll 中。第一个参数有问题。并且该函数返回 error_t = 0 即使它实际上失败了。无论如何,谢谢!
猜你喜欢
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多