You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的所在目录,导致运行时找不到。

具体修复步骤:

  1. 规范编译定义的设置:不要通过CMAKE_CXX_FLAGS全局定义_WINDLL,应针对目标单独设置,避免影响其他模块。修改Hello/lib/CMakeLists.txt:
    # 替换原set(CMAKE_CXX_FLAGS "-D_WINDLL")
    target_compile_definitions(foo PRIVATE _WINDLL)
    
  2. 修复测试的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()
    
  3. 添加必要的头文件:使用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;
    }
    
  4. 替换过时的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:10:02