资源管理设计模式
Resource Management Design Patterns
各种 API 需要调用初始化和终结方法。最近我在使用 Python C++ API 时遇到了这个问题,其中所有 API 调用必须在对 Py_Initialize
和 Py_FinalizeEx
的调用之间进行。我目前的解决方案是将此类调用放在 main 方法的开头和结尾。这看起来并不理想,因为它将 API 的实际使用与其资源管理分开。也就是说,进行 API 调用的软件组件依赖于 main 方法来获取和销毁资源。
是否有一种模式通常适用于这种场景?
这是我目前正在做的事情。
int redirected(int argc, char *argv[]) {
// Actual main method
return 0;
}
int main(int argc, char *argv[]) {
auto program = Py_DecodeLocale(argv[0], NULL);
if (program)
Py_SetProgramName(program);
else
throw new std::runtime_error("Py_SetProgramName");
Py_Initialize();
int errc = redirected(argc, argv);
if (Py_FinalizeEx() < 0)
throw new std::runtime_error("Py_FinalizeEx");
PyMem_RawFree(program);
return errc;
}
C++ 中的正确模式是使用 RAII。事实上,这是一个很好的问题。
这意味着对象的构造函数将获取资源,而析构函数将释放它。通过这种方式,您可以确保在超出范围时始终释放资源。
对于Python,它将是:
class PyInit
{
public:
PyInit() {Py_Initialize();}
~PyInit() {Py_Finalize();}
}
然后在主要部分:
int main()
{
PyInit pyinit;
// using Python interpreter
return 0;
}
各种 API 需要调用初始化和终结方法。最近我在使用 Python C++ API 时遇到了这个问题,其中所有 API 调用必须在对 Py_Initialize
和 Py_FinalizeEx
的调用之间进行。我目前的解决方案是将此类调用放在 main 方法的开头和结尾。这看起来并不理想,因为它将 API 的实际使用与其资源管理分开。也就是说,进行 API 调用的软件组件依赖于 main 方法来获取和销毁资源。
是否有一种模式通常适用于这种场景?
这是我目前正在做的事情。
int redirected(int argc, char *argv[]) {
// Actual main method
return 0;
}
int main(int argc, char *argv[]) {
auto program = Py_DecodeLocale(argv[0], NULL);
if (program)
Py_SetProgramName(program);
else
throw new std::runtime_error("Py_SetProgramName");
Py_Initialize();
int errc = redirected(argc, argv);
if (Py_FinalizeEx() < 0)
throw new std::runtime_error("Py_FinalizeEx");
PyMem_RawFree(program);
return errc;
}
C++ 中的正确模式是使用 RAII。事实上,这是一个很好的问题。
这意味着对象的构造函数将获取资源,而析构函数将释放它。通过这种方式,您可以确保在超出范围时始终释放资源。
对于Python,它将是:
class PyInit
{
public:
PyInit() {Py_Initialize();}
~PyInit() {Py_Finalize();}
}
然后在主要部分:
int main()
{
PyInit pyinit;
// using Python interpreter
return 0;
}