MSYS2环境中使用std::string导致CTest报0xc0000135错误求助
问题描述
在Win11系统的MSYS2/mingw64、clang64环境下搭建的CMake项目,当共享库foo的foo()函数中添加std::string声明后,CTest执行测试用例test0会报0xc0000135错误;未添加时测试正常,且该项目在CentOS 7x、Rocky 9x等Linux环境下运行无问题。
项目结构
Hello/ |__build/ |__CMakeLists.txt |__lib/ |__CMakeLists.txt |__foo.cpp |__foo.h |__tests/ |__CMakeLists.txt |__test0.cpp
错误信息
> ctest Test project D:/Hello/build Start 1: test0 1/1 Test #1: test0 ............................Exit code 0xc0000135 ***Exception: 0.02 sec 0% tests passed, 1 tests failed out of 1 Total Test time (real) = 0.02 sec The following tests FAILED: 1 - test0 (Exit code 0xc0000135 ) Errors while running CTest Output from these tests are in: D:/KC/msys64/home/user/hello-07.std/build/Testing/Temporary/LastTest.log
相关源码及CMake配置
Hello/CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(Hello) enable_testing() include(CTest) subdirs(lib)
Hello/lib/CMakeLists.txt
set(CMAKE_CXX_FLAGS "-D_WINDLL") add_library(foo SHARED foo.cpp foo.h) target_include_directories(foo PRIVATE .) subdirs(tests)
Hello/lib/tests/CMakeLists.txt
add_executable(test0 test0.cpp) target_include_directories(test0 PRIVATE ${PROJECT_SOURCE_DIR}/lib) target_link_libraries(test0 foo) add_test(NAME test0 COMMAND test0) if (WIN32) set_tests_properties(test0 PROPERTIES ENVIRONMENT "PATH=${CMAKE_CURRENT_BINARY_DIR}\..;$ENV{PATH}" ) endif()
Hello/lib/foo.h
#ifndef __FOO_H #define __FOO_H #ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <stdlib.h> #ifdef _WIN32 #ifdef _WINDLL #define API __declspec(dllexport) #else #define API __declspec(dllimport) #endif #else #define API #endif API int foo(int in); #ifdef __cplusplus } #endif #endif /* __FOO_H */
Hello/lib/foo.cpp
#include <foo.h> API int foo(int i) { // std::string msg = "HELLO"; // uncomment this will cause strange error !! printf("hello %d\n", i); return i; }
Hello/lib/tests/test0.cpp
#include <foo.h> int main(int argc, char *argv[]) { return foo(0); }
解决建议
0xc0000135是Windows系统的典型错误,代表程序无法找到依赖的动态链接库(DLL)。当你在foo()中使用std::string后,共享库foo.dll会依赖MSYS2环境中的C++标准库DLL(如libstdc++-6.dll或libc++.dll,取决于使用gcc还是clang),但当前测试的PATH配置未包含该DLL的所在目录,导致运行时找不到。
具体修复步骤:
- 规范编译定义的设置:不要通过
CMAKE_CXX_FLAGS全局定义_WINDLL,应针对目标单独设置,避免影响其他模块。修改Hello/lib/CMakeLists.txt:# 替换原set(CMAKE_CXX_FLAGS "-D_WINDLL") target_compile_definitions(foo PRIVATE _WINDLL) - 修复测试的PATH配置:将C++标准库的目录加入测试程序的运行PATH中,修改
Hello/lib/tests/CMakeLists.txt:if (WIN32) # 获取C++标准库所在目录 list(GET CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES 0 CXX_STD_LIB_DIR) set_tests_properties(test0 PROPERTIES ENVIRONMENT "PATH=${CMAKE_CURRENT_BINARY_DIR}/..;${CXX_STD_LIB_DIR};$ENV{PATH}" ) endif() - 添加必要的头文件:使用
std::string必须包含<string>头文件,否则属于未定义行为。修改Hello/lib/foo.cpp:#include <foo.h> #include <string> // 添加这一行 API int foo(int i) { std::string msg = "HELLO"; printf("hello %d\n", i); return i; } - 替换过时的CMake命令:
subdirs命令已被CMake标记为过时,推荐使用add_subdirectory替代。修改:Hello/CMakeLists.txt中的subdirs(lib)改为add_subdirectory(lib)Hello/lib/CMakeLists.txt中的subdirs(tests)改为add_subdirectory(tests)
内容的提问来源于stack exchange,提问作者KCC
相关产品推荐
相关产品推荐

