I am trying to embed Python in C++. I am trying to use the documented API for configuring the Python system path so that arbitrary modules can be imported from C++. But the path is not being configured correctly because my module cannot be imported unless I move it into the same directory as the executable. Clearly I am not using the API correctly. Here is my code:
error_t init_path(PyConfig* config, wchar_t** paths, int num_paths) {
if (num_paths) {
PyStatus status;
//status = PyConfig_SetBytesString(config, &config->program_name, "C:/Python311/python.exe");
//status = PyConfig_SetBytesString(config, &config->program_name, "D:/work/projects/common_hdl/pysim/cosim/x64/Debug/cosim.exe");
status = PyConfig_Read(config);
config->module_search_paths_set = 1;
for (int i = 0; i < num_paths; i++) {
status = PyWideStringList_Append(&config->module_search_paths, paths[i]);
if (PyStatus_Exception(status)) {
fprintf(stderr, "Could not add path %ls\n", paths[i]);
return PATH_INSERTION_ERR;
}
else {
printf("Appending %ls to system path\n", paths[i]);
}
}
status = Py_InitializeFromConfig(config);
if (PyStatus_Exception(status)) {
fprintf(stderr, "Unable to initialize python\n");
return INIT_ERR;
}
}
return NONE;
}
I think the documented steps to initializing the path are:
- Initialize the PyConfig data structure
- Set the program_name in the data structure
- Read the configuration data
- Set the module_search_paths_set field to 1
- Use the PyWideStringList_Append method to append the "module_search_paths" field in the data structure.
- Run the Py_InitializeFromConfig method with the new configuration.
But...
It is very unclear from the Python documentation what the "program_name" is referring to and why (or if) it needs to be initialized. I have tried some experiments as you can see in my code.
And the code above simply doesn't work. Can anyone spot the problem or fix my interpretation of the configuration process? I know there are other methods that will allow for python code to be run that will manipulate the system path. But I really would like to use the API means of doing this.