Python ctypes 如何拒绝带参数的函数调用,而函数不带参数

问题描述 投票:0回答:1

在 C++ 中,我在共享库中创建了一个 C 链接函数,如下所示:

#include <iostream>
extern "C" int myfunc()
{
  std::cout << "Hello myfunc" << std::endl;
  return 1;
}

注意该函数不需要任何参数,如果有人尝试使用参数调用它,我想生成一个错误。

我打算使用 ctypes 从 python 调用该函数,如下所示:

#!/usr/bin/python3
from ctypes import *
libmylib = cdll.LoadLibrary("./libmylib.so")
libmylib.myfunc.argtypes = []
return_code = libmylib.myfunc()
print(f"return_code={return_code:d}")

当我运行 python 脚本时,它会产生预期的输出:

Hello myfunc
return_code=1

为了测试它,我将函数的调用从 python 更改为另外传递一些参数,即我想要拒绝的行为。 例如:

return_code = libmylib.myfunc(123)
#or
return_code = libmylib.myfunc("123")

但是它仍然执行 myfunc 没有任何错误,并且似乎只是忽略了我“错误”提供了一些参数。

我尝试更改 argtypes 行,但似乎没有任何行为具有所需的行为:

libmylib.myfunc.argtypes = None
#or
libmylib.myfunc.argtypes = ()

ctypes 是否有可能检测并拒绝这些参数,或者我是否只需要接受 myfunc 可以使用额外的参数调用,而我应该忽略它们,而不是对此如此挑剔?

我可以在 python 中编写一个包装垫片函数,它可以检测额外的参数并在检测发生时生成错误,但实际上我希望避免这样做。

python ctypes
1个回答
0
投票

正如 EmilioSilva 在他的评论中提到的,这是设计使然。 引用自: https://docs.python.org/3/library/ctypes.html#ctypes._FuncPtr.argtypes

使用 C 调用约定的函数也接受其他未指定的参数

因此,为了获得所需的行为,我们需要一个垫片包装器。

在我们考虑函数没有参数的情况下,它是一个非常简单的垫片包装器:

def myfunc():
  return libmylib.myfunc()

不带参数调用 myfunc 可按预期工作:

return_code = myfunc()
print(f"return_code={return_code:d}")

使用 args 调用 myfunc 也会根据需要失败:

# trigger an error when the caller tries to do this
return_code = myfunc(123)

这是错误...

Traceback (most recent call last):
  File "testmyfunc.py", line 15, in <module>
    return_code = myfunc(123)
TypeError: myfunc() takes 0 positional arguments but 1 was given
© www.soinside.com 2019 - 2024. All rights reserved.