1

假设我有以下 SWIG 接口文件

%include "std_string.i"

%module Test %{
    std::string AmIABoolean(bool b)
    {
        return b ? "Sure" : "Yes I am";
    }
%}

std::string AmIABoolean(bool b);

当从 Python 与此模块交互时,这在实际传递布尔值时效果很好。

>>> Test.AmIABoolean(False)
"Yes I am"
>>> Test.AmIABoolean(True)
'Sure'

但令我惊讶(和沮丧)SWIG 接受此特定测试函数的任何参数

>>> Test.AmIABoolean([])
"Yes I am"
>>> Test.AmIABoolean("Free beer")
'Sure'

有没有办法以 SWIG 将 C++ 匹配到 python 方法的方式强制执行更严格的类型检查?显然,这个示例不是很有意义,但是如果我有一个具有多个重载的方法并且一个接受布尔参数,这意味着 SWIG 总是适用于接受布尔值的特定重载,这是非常不可取的。

看看 SWIG 在接口文件中检查布尔类型的方式,这种行为并不奇怪

SWIGINTERN int
SWIG_AsVal_bool (PyObject *obj, bool *val)
{
  int r = PyObject_IsTrue(obj);
  if (r == -1)
    return SWIG_ERROR;
  if (val) *val = r ? true : false;
  return SWIG_OK;
}

正如 Python 文档所说的 PyObject_IsTrue

如果对象 o 被认为为真,则返回 1,否则返回 0。这相当于 Python 表达式 not not o。失败时,返回-1。

在动态打字的美妙世界中,“免费啤酒”总是评估为真

>>> not not "Free beer"
True

但可以肯定的是,SWIG 必须能够区分一个真的值和一个恰好评估为真的值。任何帮助深表感谢。

4

0 回答 0