【问题标题】:How to fix "swig/python detected a memory leak of type 'HWND *', no destructor found"?如何修复“swig/python 检测到 'HWND *' 类型的内存泄漏,未找到析构函数”?
【发布时间】:2021-03-23 14:54:37
【问题描述】:

考虑一下这个 mcve:

mcve.h

#pragma once

#include <windows.h>

class Windows {
  public:
    static HWND GetActiveWindow();
    static HWND GetForegroundWindow();
};

mcve.cpp

#include "mcve.h"

HWND Windows::GetActiveWindow() {
    return ::GetActiveWindow();
}
HWND Windows::GetForegroundWindow() {
    return ::GetForegroundWindow();
}

mcve.i

%module mcve

%include <std_string.i>
%include <std_vector.i>
%include <typemaps.i>
%include <windows.i>
%include <cpointer.i>
%include <carrays.i>

%{
#include "mcve.h"
%}


%include "mcve.h"

setup.py

from distutils.core import Extension
from distutils.core import setup

setup(
    name="mcve",
    ext_modules=[
        Extension(
            "_mcve",
            sources=["mcve.i", "mcve.cpp", "mcve_wrap.cpp"],
            swig_opts=["-c++", "-python"],
            include_dirs=["."],
            library_dirs=[
              "D:/software/vcpkg/installed/x86-windows/lib"
            ],
            libraries=["user32"]
        )
    ],
    py_modules=["mcve"],
)

要运行它,请确保正确调整 library_dirs 变量,然后只需键入:

python setup.py build_ext --inplace

如果扩展已成功生成,那么您只需运行python test.py,您应该会看到类似以下的输出:

>python test.py
swig/python detected a memory leak of type 'HWND *', no destructor found.
swig/python detected a memory leak of type 'HWND *', no destructor found.

我知道你可以使用 swig -nodefaultdtor 来不生成隐式默认析构函数,我已经尝试过,但没有任何区别。

为了完整起见,HWND typedef 大致如下所示:

typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef void *PVOID;

问题: swig 中防止 HWND 内存泄漏的正确方法是什么?

【问题讨论】:

标签: python c++ windows memory-leaks swig


【解决方案1】:

SWIG 未提供 HWND 的定义,并将其视为不透明类。请注意,%include "mcve.h" 不会递归到 #include &lt;windows.h&gt;,而只会直接在 mcve.h 中处理代码,因此 SWIG 根本没有定义。

有几个解决方案:

  • 给 SWIG 一个它可以理解的定义。 SWIG 具有 void* 的默认值,并且可以正确处理以下定义:
%module mcve

%{
#include "mcve.h"
%}

typedef void* HWND;

%include "mcve.h"
  • 您可以制作自定义类型映射,以指导 Python 如何将 HWND 与 Python 对象相互转换。与返回 SWIG 包装的 void* 对象的先前解决方案不同,此解决方案将句柄视为整数:
%module mcve

%{
#include "mcve.h"
%}

%typemap(in) HWND %{
    $1 = PyLong_AsVoidPtr($input);
%}

%typemap(out) HWND %{
    $result = PyLong_FromVoidPtr($1);
%}

%include "mcve.h"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    相关资源
    最近更新 更多