У меня есть синглтон, определенный в C ++, который я хочу подвергнуть Python. Python, кажется, создает новый экземпляр Singleton, независимо от того, как я его связываю. Мой основной код находится в основной библиотеке, с которой модуль Python также связан. < /P>
cmake_minimum_required(VERSION 3.12)
project(pybind-singleton)
cmake_policy(SET CMP0148 NEW)
set(CMAKE_CXX_STANDARD 17)
find_package(pybind11 CONFIG REQUIRED)
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
add_library(my_lib SHARED
src/Singleton.cpp
)
message(STATUS "Python include dirs: " ${PYTHON_INCLUDE_DIRS})
message(STATUS "pybind include dirs: " ${pybind11_INCLUDE_DIRS})
target_include_directories(my_lib PUBLIC include ${PYTHON_INCLUDE_DIRS} ${pybind11_INCLUDE_DIRS})
target_link_libraries(my_lib PUBLIC Python3::Python)
pybind11_add_module(my_module src/binding.cpp)
target_link_libraries(my_module PUBLIC my_lib)
add_executable(${CMAKE_PROJECT_NAME} src/main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC my_lib)
< /code>
class Singleton
{
public:
static Singleton &GetInstance()
{
static Singleton instance;
return instance;
}
Singleton(Singleton const &) = delete;
void operator=(Singleton const &) = delete;
std::string test;
void Init();
void PrintTest();
private:
Singleton(){};
};
< /code>
namespace py = pybind11;
PYBIND11_MODULE(my_module, m)
{
py::class_(m, "Singleton")
.def_static(
"print_test", []()
{ Singleton::GetInstance().PrintTest(); },
py::return_value_policy::reference)
.def_static(
"get_test_val", []()
{
Singleton &singleton = Singleton::GetInstance();
return singleton.test; },
py::return_value_policy::reference)
.def_static(
"get_instance", &Singleton::GetInstance, py::return_value_policy::reference)
.def_readwrite("test", &Singleton::test);
}
< /code>
from my_module import Singleton
print('Accessing Singleton...')
test_val = Singleton.get_test_val()
print('Test val:', test_val if test_val != '' else 'None')
print('--')
Singleton.print_test()
print('--')
instance = Singleton.get_instance()
print(instance)
print(instance.test)
instance.test = 'Python\'s instance'
print(instance.test)
instance.print_test()
< /code>
% ./pybind-singleton
Instancing Singleton...
/Users/jordan/dev/pybind-singleton/src/Singleton.cpp: 12
/Users/jordan/dev/pybind-singleton/src/Singleton.cpp: 12
C++'s instance
------------
Running init.py
Accessing Singleton...
Test val: None
--
/Users/jordan/dev/pybind-singleton/src/Singleton.cpp: 12
--
Python's instance
/Users/jordan/dev/pybind-singleton/src/Singleton.cpp: 12
Python's instance
< /code>
I've made up a minimal example in this repo; some of the code has been omitted from above for brevity: https://github.com/jordanlevy96/pybind-singleton
Подробнее здесь: https://stackoverflow.com/questions/777 ... -libraries