在 C++ 中捕獲 Python 異常
在開發一個伺服器-客戶端應用時,客戶端會呼叫伺服器的 API,該 API 提供了用於使用者輸入的 Python 介面。這意味著客戶端介面和伺服器介面是用 Python 編寫的,而套接字程式碼是用 C++ 編寫的。
我希望在 C++ 程式碼中使用 SWIG 來處理從 Python 中丟擲的異常。因此,我想知道應該在 *.i(介面)檔案中寫什麼來處理這種情況。
2、解決方案
為了實現這個功能,您需要編寫一個 %feature("director:except"),它可以處理 Python 異常並將其重新丟擲為 C++ 異常。以下是一個簡單但完整的示例:
標頭檔案 example.h
#include <iostream>
#include <exception>
class MyException : public std::exception {
};
class AnotherException : public std::exception {
};
class Callback {
public:
virtual ~Callback() { std::cout << "~Callback()" << std:: endl; }
virtual void run() { std::cout << "Callback::run()" << std::endl; }
};
inline void call(Callback *callback) { if (callback) callback->run(); }
Python 程式碼
import example
class PyCallback(example.Callback):
def __init__(self):
example.Callback.__init__(self)
def run(self):
print("PyCallback.run()")
raise example.MyException()
callback = PyCallback()
example.call(callback)
SWIG 介面檔案
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_string.i"
%include "std_except.i"
%include "pyabc.i"
// Python requires that anything we raise inherits from this
%pythonabc(MyException, Exception);
%feature("director:except") {
PyObject *etype = $error;
if (etype != NULL) {
PyObject *obj, *trace;
PyErr_Fetch(&etype, &obj, &trace);
Py_DecRef(etype);
Py_DecRef(trace);
// Not too sure if I need to call Py_DecRef for obj
void *ptr;
int res = SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_MyException, 0);
if (SWIG_IsOK(res) && ptr) {
MyException *e = reinterpret_cast< MyException * >(ptr);
// Throw by pointer (Yucky!)
throw e;
}
res = SWIG_ConvertPtr(obj, &ptr, SWIGTYPE_p_AnotherException, 0);
if (SWIG_IsOK(res) && ptr) {
AnotherException *e = reinterpret_cast< AnotherException * >(ptr);
throw e;
}
throw Swig::DirectorMethodException();
}
}
%feature("director") Callback;
%include "example.h"
程式碼會處理來自管理函式的錯誤,檢查它是否是我們 MyException 例項之一,如果是,則重新丟擲指標。如果您有多種型別的異常被丟擲,那麼您可能需要先使用 PyErr_ExceptionMatches 來計算出它的型別。
透過呼叫 SWIG 使用 -py3 引數,我們就可以讓這個示例工作(否則 %pythonabc 不起作用)。這又意味著我們必須升級到 SWIG 2.0,因為我安裝的 Python 3.2 從 C-API 中刪除了一些 SWIG 1.3.40 呼叫的已棄用的函式。
在呼叫 Python 函式後,可以使用
PyErr_Occurred()
檢查是否發生了異常,並使用
PyErr_Print()
列印異常資訊。在實際應用中,你可能需要根據你的需求進行更詳細的異常處理。
此外,要確保在 C++ 程式碼中正確處理 Python 的引用計數,避免記憶體洩漏,可以使用
Py_XDECREF
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70034537/viewspace-3006301/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python中如何捕獲異常Python
- python異常捕獲Python
- 在Python中捕獲finally語句中異常訊息Python
- python動態捕獲異常Python
- 捕獲 React 異常React
- iOS異常捕獲iOS
- 你真的會在async/await中捕獲異常嗎?AI
- android 異常捕獲-UncaughtExceptionHandlerAndroidException
- 記錄Javascript 異常捕獲JavaScript
- PHP使用trycatch,捕獲異常PHP
- 【筆記】forall 異常捕獲筆記
- 前端異常捕獲與上報前端
- PLSQL宣告部分異常捕獲SQL
- wpf 捕獲全域性異常
- 前端開發中的Error以及異常捕獲前端Error
- 儲存過程——異常捕獲&列印異常資訊儲存過程
- JS 使用try catch捕獲異常JS
- Auth 授權的異常捕獲
- 異常的捕獲及處理
- oracle異常捕獲程式碼(轉)Oracle
- 10. 異常捕獲、生成式
- MySQL儲存過程中捕獲異常的方法MySql儲存過程
- Java開發者的Python快速進修指南:異常捕獲JavaPython
- python之異常捕獲&清除的列印報錯行Python
- 中介軟體中丟擲異常,Handler中無法捕獲
- 談談前端異常捕獲與上報前端
- DRF之異常捕獲原始碼分析原始碼
- 捕獲不到異常嘗試除以0
- 【求助】如何捕獲 pytest parametrize 中的 timeout 異常
- 前端JavaScript 常見的報錯及異常捕獲前端JavaScript
- 異常處理機制(二)之異常處理與捕獲
- spring-boot 統一異常捕獲Springboot
- SpringBoot之全域性捕獲異常Spring Boot
- iOS 日誌重定向和異常捕獲iOS
- C#中有關異常的捕獲演示C#
- Android 全域性異常捕獲之CrashHandlerAndroid
- Auto.js Pro 資料獲取 與 異常捕獲JS
- Java捕獲非檢查異常----UncaughtExceptionHandler的使用JavaException