Python ctypes返回值问题

发布于 2024-11-09 01:42:04 字数 525 浏览 5 评论 0原文

为什么如果我有这个简单的代码,

void voidFunct() {
      printf("voidFunct called!!!\n");
}

我将其编译为动态库

gcc -c LSB.c -o LSB.o 
gcc -shared -Wl -o libLSB.so.1 LSB.o 

并且我使用 ctypes 从 python 解释器调用函数,

>>> from ctypes import *
>>> dll = CDLL("./libLSB.so.1")
>>> return = dll.voidFunct()
voidFunct called!!!
>>> print return
17

为什么从 void 方法返回的值是 17而不是 None 或类似的?谢谢。

Why if i have this simple code

void voidFunct() {
      printf("voidFunct called!!!\n");
}

I compile it as a dynamic library with

gcc -c LSB.c -o LSB.o 
gcc -shared -Wl -o libLSB.so.1 LSB.o 

And i call function from a python interpreter, using ctypes

>>> from ctypes import *
>>> dll = CDLL("./libLSB.so.1")
>>> return = dll.voidFunct()
voidFunct called!!!
>>> print return
17

why the value returned from a void method is 17 and not None or similar? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那支青花 2024-11-16 01:42:04

来自文档:

类 ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

此类的实例代表加载的共享库。这些库中的函数使用标准 C 调用约定,并且假定返回 int

简而言之,您将 voidFunct() 定义为返回 int 的函数,而不是 void,并且 Python 期望它返回一个 int (无论如何,它都会得到它 - 它只是恰好是一个随机值)。

您可能应该做的是显式声明返回值类型 None

dll.voidFunct.restype = None

From the docs:

class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return int.

In short, you defined voidFunct() as a functioning returning int, not void, and Python expects it to return an int (which it gets, somehow, anyway - it's just happen to be a random value).

What you should probably do, is to explicitly state a return value type of None.

dll.voidFunct.restype = None
孤云独去闲 2024-11-16 01:42:04

这是未定义的行为。您要求 ctypes 读取根本不存在的返回值。它从堆栈中读取一些内容,但返回的内容是不明确的。

That's undefined behaviour. You are asking ctypes to read a return value that is simply not there. It reads something off the stack, but what comes back is ill-defined.

农村范ル 2024-11-16 01:42:04

基于上面 Boaz Yaniv 的答案:

===QUOTE===

简而言之,您将 voidFunct() 定义为返回 int 的函数,而不是 void< /code>,Python 希望它返回一个 int

...

您可能应该做的是显式声明 None 的返回值类型:

dll.voidFunct.restype = None

===UNQUOTE===

如果研究 C 的内部结构,整数返回值将返回到调用者通过 ax/eax 寄存器,而不是通过堆栈或类似的方式。因此打印出来的值并不完全是随机的,而是函数返回时恰好位于 ax 寄存器中的值。

在这种情况下,最近使用的 ax/eax 寄存器是 printf() 语句的(未使用的)返回值 - 这是 printf() 函数写入控制台的字节数。
(请注意,字符串“voidFunct called!!!\n”的长度是 20,而不是 17。我们可以相当肯定,上面提到的 C 程序并不完全是逐字运行的)

Building on the answer from Boaz Yaniv above:

===QUOTE===

In short, you defined voidFunct() as a function returning int, not void, and Python expects it to return an int.

...

What you should probably do, is to explicitly state a return value type of None:

dll.voidFunct.restype = None

===UNQUOTE===

If one looks into the internals of C, integer return values are returned to the caller via the ax/eax register, rather than via the stack or similar. So the value being printed out is not exactly random, but the value that happens to be in the ax register when the function returned.

In this case, the most recent use of the ax/eax register was the (unused) return value from the printf() statement - which is the number of bytes written to the console by the printf() function.
(Note that the length of the string "voidFunct called!!!\n" is 20, not 17. We can be fairly sure that C program mentioned above is not exactly verbatim of what was run)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文