在析构函数中创建检查类型图

Posted

技术标签:

【中文标题】在析构函数中创建检查类型图【英文标题】:Creating check typemap except in destructor 【发布时间】:2018-12-10 17:46:05 【问题描述】:

我正在使用 SWIG 创建一个 Python 接口,以允许为我的 C++ 程序添加插件。

我有一些类可能看起来像这样:

class TStdFunc

public:
  void SetColor(unsigned);
  unsigned GetColor() const;
  bool IsValid() const;  
;

用户可以删除对象。这实际上只是将它移动到撤消堆栈,以便用户可以撤消操作。但是,当一个对象被“删除”时,我不希望插件更改它。

因此,我创建了一个这样的类型映射:

%typemap(check) TStdFunc*

  if(!$1->IsValid())
      SWIG_exception_fail(SWIG_RuntimeError, "Element is not valid");

这很好用。如果插件存储了对该对象的引用,并在“删除”对象后尝试调用 SetColor() 或 GetColor(),则会出现异常。

但是,检查也添加到 SWIG 创建的函数 _wrap_delete_TStdFunc 中。因此,当对象从 Python 中销毁时,我也会遇到异常。那么如何检查除删除功能之外的所有功能呢?我可以禁用删除功能的类型映射吗?

PS。这当然是一个简化的解释。这些对象实际上是用 boost::shared_ptr 包裹的,但我认为这并不重要。

【问题讨论】:

【参考方案1】:

我偶然找到了解决方案。在类定义之后添加这个将删除析构函数中的检查,同时将其保留在所有其他函数中。

%extend TStdFunc 

  %typemap(check) TStdFunc* ""

我认为这是可行的,因为 %extend 重新打开了类定义,并且在类的定义完成时生成了析构函数代码。

【讨论】:

【参考方案2】:

我刚刚遇到了类似的问题。 %extend 技巧在我的情况下不起作用,所以我求助于检查类型图中的函数名称,如下所示:

%typemap(check) TStdFunc* %
    if (strcmp("$symname", "delete_TStdFunc"))
        if(!$1->IsValid())
            SWIG_exception_fail(SWIG_RuntimeError, "Element is not valid");
%;

【讨论】:

以上是关于在析构函数中创建检查类型图的主要内容,如果未能解决你的问题,请参考以下文章

检查指针在析构函数中不为空[重复]

在析构函数中捕获异常

为啥在析构函数中抛出异常时不调用重载删除?

MySQLi 在析构函数中立即关闭

使用 exit 和全局对象

glDeleteBuffers() 在析构函数调用期间崩溃