【问题标题】:Ctypes catching exception from C++ [duplicate]Ctypes从C ++捕获异常[重复]
【发布时间】:2014-05-27 08:53:07
【问题描述】:

我读到了这个问题Ctypes catching exception 但就我而言,当我尝试从 C++ 抛出异常时,python.exe 总是崩溃。

我的代码和上一个问题一样:

C++:

double Divide(double a, double b)
{
  if (b == 0)
  {
    throw new invalid_argument("b cannot be zero!");
  }

  return a / b;
}

Python:

from ctypes import *

mathdll=cdll.MathFuncsDll
divide = mathdll.Divide
divide.restype = c_double
divide.argtypes = [c_double, c_double]

try:
    print divide (10,0)
except WindowsError:
    print "lalal"
except:
    print "dada"

我使用 Windows 7 x64、python 2,7 和 MinGW

是否有一些提示或技巧可以在 python 中使用 ctypes 处理来自 C++ 的异常?

【问题讨论】:

  • Ctypes catching exception 中的任何答案都没有真正解释 @nobs 如何通过抛出 C++ 异常在 Python 中引发异常。我可能会用 C++ 示例扩展我的答案并将其重新发布到那里。
  • 这是特定于 Visual C++ 的。对于 MinGW,这是不可能的,AFAIK。 C 绑定需要捕获所有异常并将它们转换为错误返回代码。您可以用 C++ 编写 Python 扩展模块,而不是使用带有 C API 的 ctypes; Cython 也支持C++ exceptions

标签: python c++ exception ctypes


【解决方案1】:

ctypes 不支持 C++ 异常,或 C++ 任何与此相关的东西。鉴于其 Windows 根源,ctypes 有一个用于 Windows 结构化异常处理 (SEH) 的处理程序。使用 MS Visual C++ 编译的库通过 SEH 实现 C++ 异常(代码 0xE06D7363,有关实现细节,请参见 this article),但 MinGW 不支持 C 中的 SEH,并且不使用它来实现 C++ 异常。

如果您不关心使您的代码跨平台,那么您可以调用 Windows API RaiseException。 ctypes 会将 SEH 异常路由到 Python OSError_call_function_pointer 使用 __try__except 关键字(Microsoft 扩展 C)设置 SEH 处理程序。 SetException 对几个异常代码进行了特殊处理,否则将转至 PyErr_SetFromWindowsErr(code)

例子:

#include <Windows.h>

__declspec(dllexport) void test()
{
    RaiseException(42, 0, 0, NULL);
}

测试:

>>> from ctypes import *
>>> lib = CDLL('./lib.dll')
>>> lib.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [WinError 42] Windows Error 0x%X

(显然PyErr_SetFromWindowsErr有bug。不支持格式代码%X;只能小写%x。假装最后一部分是Windows Error 0x2a。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2018-11-29
    • 2020-12-17
    • 2012-07-13
    • 2011-12-07
    • 2012-09-22
    • 1970-01-01
    相关资源
    最近更新 更多