Windows下用ctypes调用DLL时absl::Log初始化失败
Windows下Python ctypes调用含Abseil Log的C++动态库触发访问冲突
在Windows+MSVC环境中,使用C++开发动态库并通过Python的ctypes调用库中函数时,初始化absl::Log会触发访问冲突错误:
OSError: exception: access violation reading 0x0000000000000000
相同代码在macOS+Clang环境下可正常运行,且Windows下将代码编译为可执行文件时也能正常执行。
复现代码
main.cpp
#include "absl/base/log_severity.h" #include "absl/log/globals.h" #include "absl/log/initialize.h" #include "absl/log/log.h" #include <iostream> #ifdef _WIN32 #define C_API __declspec(dllexport) #else #define C_API #endif extern "C" { C_API void initializeAbslLoggingPy() { LOG(INFO) << "initializing absl log"; absl::InitializeLog(); absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo); LOG(INFO) << "absl log initialized"; } }
CMakeLists.txt
cmake_minimum_required(VERSION 3.25) project(osm2gmns VERSION 1.0.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) include(FetchContent) set(FETCHCONTENT_QUIET OFF) SET(ABSL_PROPAGATE_CXX_STD ON) SET(ABSL_BUILD_TESTING OFF) FetchContent_Declare( absl GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git GIT_TAG 20230125.3 SYSTEM ) FetchContent_MakeAvailable(absl) add_library(main SHARED main.cpp) target_link_libraries(main PRIVATE absl::log absl::log_initialize)
main.py
import ctypes import os oglib = ctypes.CDLL(os.path.join(os.path.dirname(__file__), 'main.dll')) oglib.initializeAbslLoggingPy.argtypes = [] oglib.initializeAbslLoggingPy()
错误输出
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR I0000 00:00:1721963952.103176 15648 main.cpp:17] initializing absl log Traceback (most recent call last): File "c:\Users\Jiawei\Desktop\og\absl\test\main.py", line 6, in <module> oglib.initializeAbslLoggingPy() OSError: exception: access violation reading 0x0000000000000000
可正常运行的Windows可执行文件代码
#include "absl/base/log_severity.h" #include "absl/log/globals.h" #include "absl/log/initialize.h" #include "absl/log/log.h" #include <iostream> int main() { LOG(INFO) << "initializing absl log"; absl::InitializeLog(); absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo); LOG(INFO) << "absl log initialized"; }
内容的提问来源于stack exchange,提问作者Jiawei Lu
相关产品推荐
相关产品推荐

