Reputation: 23
Various APIs require calls to initialization and finalization methods. Most recently I've come across this while using the Python C++ API, where all API calls must be between calls to Py_Initialize
and Py_FinalizeEx
. My current solution is to put such calls at the beginning and end of the main method. This does not seem ideal, as it separates the actual usage of the API from it's resource management. That is, the software components which make API calls rely on the main method to acquire and destroy the resources.
Is there a pattern that is usually applied in such a scenario?
Here is what I'm currently doing.
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;
}
Upvotes: 2
Views: 469
Reputation: 22023
The proper pattern in C++ is using RAII. And indeed, it's a very good question.
This means that the constructor of an object will acquire the resource and the destructor will release it. This way you ensure that the resource will always be freed when you get out of scope.
For Python, it would be:
class PyInit
{
public:
PyInit() {Py_Initialize();}
~PyInit() {Py_Finalize();}
}
And then in main:
int main()
{
PyInit pyinit;
// using Python interpreter
return 0;
}
Upvotes: 3