[直接上测试代码]

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <fstream>
#include <exception>

// 测试跨模块内存管理冲突的函数
extern "C" {
__declspec(dllexport) void* allocate_in_lib(size_t size);
__declspec(dllexport) void free_in_lib(void* ptr);
__declspec(dllexport) std::string* create_string_in_lib();
__declspec(dllexport) void destroy_string_in_lib(std::string* str);
}

// 在当前模块中实现这些函数
void* allocate_in_lib(size_t size) {
return malloc(size);
}

void free_in_lib(void* ptr) {
free(ptr);
}

std::string* create_string_in_lib() {
return new std::string("Created in VS2017 module");
}

void destroy_string_in_lib(std::string* str) {
delete str;
}

只不过现在要把它在VS2017编译为引用了静态CRT的动态库模块(由此绕过链接期警告,但实则会出现全局两份CRT副本)

现在做出的模块它就是货真价实静态编译(引入了静态CRT)的动态库了

然后是主程run中的代码我们直接放在VS2019里

// 测试异常跨边界的函数
class CustomException : public std::exception {
private:
std::string message;
public:
CustomException(const std::string& msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};

void throw_exception_from_lib() {
throw CustomException("Exception from VS2017 module");
}

// 测试IO操作的函数
void test_file_operations() {
std::ofstream file("test_vs2017.txt");
file << "Hello from VS2017 CRT" << std::endl;
file.close();

std::ifstream infile("test_vs2017.txt");
std::string content;
std::getline(infile, content);
infile.close();

std::cout << "File content: " << content << std::endl;
}

// 测试STL容器的跨模块使用
std::vector<int>* create_vector_in_lib() {
auto* vec = new std::vector<int>{ 1, 2, 3, 4, 5 };
return vec;
}

void destroy_vector_in_lib(std::vector<int>* vec) {
delete vec;
}


void
run() {

std::cout << "VS2017 CRT Test Program" << std::endl;

// 测试1: 基本内存分配/释放
void* ptr = allocate_in_lib(100);
if (ptr) {
std::cout << "Memory allocated in lib: " << ptr << std::endl;
free_in_lib(ptr);
}

// 测试2: string对象的创建和销毁
std::string* str = create_string_in_lib();
if (str) {
std::cout << "String from lib: " << *str << std::endl;
destroy_string_in_lib(str);
}

// 测试3: 异常处理
try {
throw_exception_from_lib();
} catch (const CustomException& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}

// 测试4: 文件IO操作
test_file_operations();

// 测试5: STL容器
std::vector<int>* vec = create_vector_in_lib();
if (vec) {
std::cout << "Vector size: " << vec->size() << std::endl;
for (const auto& item : *vec) {
std::cout << "Item: " << item << std::endl;
}
destroy_vector_in_lib(vec);
}

// 测试6: 智能指针跨模块使用
auto shared_ptr = std::make_shared<int>(42);
std::cout << "Shared pointer value: " << *shared_ptr << std::endl;
std::cout << "Shared pointer use count: " << shared_ptr.use_count() << std::endl;

// 测试7: 静态对象初始化顺序
static int static_var = []() {
std::cout << "Static variable initialized in VS2017 module" << std::endl;
return 100;
}();

std::cout << "Static variable value: " << static_var << std::endl;

std::cout << "Program completed successfully" << std::endl;
}

 

直接编译/链接肯定是没问题的

运行的时候记得把dll从模块中解压复制到运行目录

运行结果来看也没什么问题!说明在VS2017与VS2019即便存在2份CRT副本(一份动态库中的CRT静态版,一份主程中的CRT动态版)它们依旧还是ABI兼容的


 

[周目二,接下来测试的才是重头戏吧]

// 这个文件将编译成VS2017动态库(声明的CRT为静态库),测试全局状态函数

#include
<iostream>

#include <locale.h>
#include <exception>
#include <new>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iomanip>

#define EXP __declspec(dllexport)

// 测试locale设置
EXP void vs2017_set_locale() {
std::cout << "=== VS2017 Setting Locale ===" << std::endl;

// 设置为德语区域
setlocale(LC_ALL, "German_Germany.1252");

// 测试数字格式
double number = 1234.56;
printf("VS2017: German locale number: %.2f\n", number);

// 测试时间格式
time_t now = time(nullptr);
struct tm* timeinfo = localtime(&now);
char buffer[80];
strftime(buffer, sizeof(buffer), "%A, %d %B %Y", timeinfo);
printf("VS2017: German date: %s\n", buffer);

// 验证当前locale
const char* current_locale = setlocale(LC_ALL, nullptr);
printf("VS2017: Current locale: %s\n", current_locale ? current_locale : "NULL");
}

// 测试异常处理器
EXP void vs2017_set_terminate_handler() {
std::cout << "\n=== VS2017 Setting Terminate Handler ===" << std::endl;

static bool vs2017_handler_called = false;

auto old_handler = std::set_terminate([]() {
std::cout << "VS2017: Custom terminate handler called!" << std::endl;
vs2017_handler_called = true;
std::abort();
});

std::cout << "VS2017: Terminate handler set" << std::endl;
std::cout << "VS2017: Previous handler was: " << (old_handler ? "set" : "null") << std::endl;
}

// 测试new_handler
EXP void vs2017_set_new_handler() {
std::cout << "\n=== VS2017 Setting New Handler ===" << std::endl;

static bool vs2017_new_handler_called = false;

auto old_handler = std::set_new_handler([]() {
std::cout << "VS2017: Custom new handler called!" << std::endl;
vs2017_new_handler_called = true;
throw std::bad_alloc();
});

std::cout << "VS2017: New handler set" << std::endl;
std::cout << "VS2017: Previous new handler was: " << (old_handler ? "set" : "null") << std::endl;
}

// 测试环境变量
EXP void vs2017_set_environment() {
std::cout << "\n=== VS2017 Setting Environment ===" << std::endl;

// 设置环境变量
int result = _putenv("VS2017_VAR=FromVS2017CRT");
std::cout << "VS2017: _putenv result: " << result << std::endl;

// 读取环境变量
char* env_value = getenv("VS2017_VAR");
std::cout << "VS2017: VS2017_VAR = " << (env_value ? env_value : "NULL") << std::endl;

// 设置另一个变量
_putenv("SHARED_VAR=VS2017_Setting");
env_value = getenv("SHARED_VAR");
std::cout << "VS2017: SHARED_VAR = " << (env_value ? env_value : "NULL") << std::endl;
}

// 测试时区设置
EXP void vs2017_set_timezone() {
std::cout << "\n=== VS2017 Setting Timezone ===" << std::endl;

// 设置时区
_putenv("TZ=PST8PDT");
tzset();

// 显示时区信息
time_t now = time(nullptr);
struct tm* timeinfo = localtime(&now);

std::cout << "VS2017: Timezone set to PST" << std::endl;
// tm_gmtoff不是标准C++,使用timezone代替
long timezone_diff = _timezone;
std::cout << "VS2017: Current time offset: " << timezone_diff << " seconds" << std::endl;
std::cout << "VS2017: Daylight saving: " << (timeinfo->tm_isdst ? "Yes" : "No") << std::endl;
}

// 综合测试函数
EXP void vs2017_global_state_test() {
std::cout << "=== VS2017 Global State Test Started ===" << std::endl;

vs2017_set_locale();
vs2017_set_terminate_handler();
vs2017_set_new_handler();
vs2017_set_environment();
vs2017_set_timezone();

std::cout << "\n=== VS2017 Global State Test Completed ===" << std::endl;
}

// 检查当前状态的函数
EXP void vs2017_check_current_state() {
std::cout << "\n=== VS2017 Checking Current State ===" << std::endl;

// 检查locale
const char* current_locale = setlocale(LC_ALL, nullptr);
std::cout << "VS2017: Current locale: " << (current_locale ? current_locale : "NULL") << std::endl;

// 检查环境变量
char* vs2017_var = getenv("VS2017_VAR");
char* shared_var = getenv("SHARED_VAR");
char* vs2019_var = getenv("VS2019_VAR");

std::cout << "VS2017: VS2017_VAR = " << (vs2017_var ? vs2017_var : "NULL") << std::endl;
std::cout << "VS2017: SHARED_VAR = " << (shared_var ? shared_var : "NULL") << std::endl;
std::cout << "VS2017: VS2019_VAR = " << (vs2019_var ? vs2019_var : "NULL") << std::endl;

// 检查数字格式
double test_number = 1234.56;
std::cout << "VS2017: Number format test: " << test_number << std::endl;
}
// VS2019主程序(就常规声明CRT动态库),将调用VS2017库并测试全局状态冲突


#include <iostream>
#include <locale.h>
#include <exception>
#include <new>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iomanip>

// 声明VS2017库中的函数
void vs2017_global_state_test();
void vs2017_check_current_state();

// VS2019特有的全局状态测试函数
void vs2019_set_locale() {
   std::cout << "=== VS2019 Setting Locale ===" << std::endl;
   
   // 设置为法语区域
   setlocale(LC_ALL, "French_France.1252");
   
   // 测试数字格式
   double number = 1234.56;
   printf("VS2019: French locale number: %.2f\n", number);
   
   // 测试时间格式
   time_t now = time(nullptr);
   struct tm* timeinfo = localtime(&now);
   char buffer[80];
   strftime(buffer, sizeof(buffer), "%A, %d %B %Y", timeinfo);
   printf("VS2019: French date: %s\n", buffer);
   
   // 验证当前locale
   const char* current_locale = setlocale(LC_ALL, nullptr);
   printf("VS2019: Current locale: %s\n", current_locale ? current_locale : "NULL");
}

void vs2019_set_terminate_handler() {
   std::cout << "\n=== VS2019 Setting Terminate Handler ===" << std::endl;
   
   static bool vs2019_handler_called = false;
   
   auto old_handler = std::set_terminate([]() {
       std::cout << "VS2019: Custom terminate handler called!" << std::endl;
       vs2019_handler_called = true;
       std::abort();
   });
   
   std::cout << "VS2019: Terminate handler set" << std::endl;
   std::cout << "VS2019: Previous handler was: " << (old_handler ? "set" : "null") << std::endl;
}

void vs2019_set_new_handler() {
   std::cout << "\n=== VS2019 Setting New Handler ===" << std::endl;
   
   static bool vs2019_new_handler_called = false;
   
   auto old_handler = std::set_new_handler([]() {
       std::cout << "VS2019: Custom new handler called!" << std::endl;
       vs2019_new_handler_called = true;
       throw std::bad_alloc();
   });
   
   std::cout << "VS2019: New handler set" << std::endl;
   std::cout << "VS2019: Previous new handler was: " << (old_handler ? "set" : "null") << std::endl;
}

void vs2019_set_environment() {
   std::cout << "\n=== VS2019 Setting Environment ===" << std::endl;
   
   // 设置环境变量
   int result = _putenv("VS2019_VAR=FromVS2019CRT");
   std::cout << "VS2019: _putenv result: " << result << std::endl;
   
   // 读取环境变量
   char* env_value = getenv("VS2019_VAR");
   std::cout << "VS2019: VS2019_VAR = " << (env_value ? env_value : "NULL") << std::endl;
   
   // 修改共享变量
   _putenv("SHARED_VAR=VS2019_Modified");
   env_value = getenv("SHARED_VAR");
   std::cout << "VS2019: SHARED_VAR = " << (env_value ? env_value : "NULL") << std::endl;
}

void vs2019_set_timezone() {
   std::cout << "\n=== VS2019 Setting Timezone ===" << std::endl;
   
   // 设置不同时区
   _putenv("TZ=EST5EDT");
   tzset();
   
   // 显示时区信息
   time_t now = time(nullptr);
   struct tm* timeinfo = localtime(&now);
   
   std::cout << "VS2019: Timezone set to EST" << std::endl;
   // tm_gmtoff不是标准C++,使用timezone代替
   long timezone_diff = _timezone;
   std::cout << "VS2019: Current time offset: " << timezone_diff << " seconds" << std::endl;
   std::cout << "VS2019: Daylight saving: " << (timeinfo->tm_isdst ? "Yes" : "No") << std::endl;
}

void vs2019_global_state_test() {
   std::cout << "=== VS2019 Global State Test Started ===" << std::endl;
   
   vs2019_set_locale();
   vs2019_set_terminate_handler();
   vs2019_set_new_handler();
   vs2019_set_environment();
   vs2019_set_timezone();
   
   std::cout << "\n=== VS2019 Global State Test Completed ===" << std::endl;
}

void vs2019_check_current_state() {
   std::cout << "\n=== VS2019 Checking Current State ===" << std::endl;
   
   // 检查locale
   const char* current_locale = setlocale(LC_ALL, nullptr);
   std::cout << "VS2019: Current locale: " << (current_locale ? current_locale : "NULL") << std::endl;
   
   // 检查环境变量
   char* vs2017_var = getenv("VS2017_VAR");
   char* shared_var = getenv("SHARED_VAR");
   char* vs2019_var = getenv("VS2019_VAR");
   
   std::cout << "VS2019: VS2017_VAR = " << (vs2017_var ? vs2017_var : "NULL") << std::endl;
   std::cout << "VS2019: SHARED_VAR = " << (shared_var ? shared_var : "NULL") << std::endl;
   std::cout << "VS2019: VS2019_VAR = " << (vs2019_var ? vs2019_var : "NULL") << std::endl;
   
   // 检查数字格式
   double test_number = 1234.56;
   std::cout << "VS2019: Number format test: " << test_number << std::endl;
}

int main() {
   std::cout << "=== Global State Conflict Test ===" << std::endl;
   std::cout << "Testing CRT global state sharing between VS2017 and VS2019" << std::endl;
   
   // 步骤1: VS2019设置自己的全局状态
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "STEP 1: VS2019 Setting Initial Global State" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   vs2019_global_state_test();
   vs2019_check_current_state();
   
   // 步骤2: 调用VS2017库,让它修改全局状态
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "STEP 2: Calling VS2017 Library" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   vs2017_global_state_test();
   
   // 步骤3: VS2019检查全局状态是否被影响
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "STEP 3: VS2019 Checking State After VS2017 Call" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   vs2019_check_current_state();
   
   // 步骤4: 让VS2017也检查当前状态
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "STEP 4: VS2017 Checking Current State" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   vs2017_check_current_state();
   
   // 步骤5: VS2019再次修改状态,观察是否影响VS2017
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "STEP 5: VS2019 Modifying State Again" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   // 修改locale为英语
   setlocale(LC_ALL, "English_United States.1252");
   _putenv("FINAL_VAR=VS2019_Final");
   
   std::cout << "VS2019: Set locale to English and added FINAL_VAR" << std::endl;
   
   // 最终检查
   std::cout << "\n" << std::string(60, '=') << std::endl;
   std::cout << "FINAL STATE CHECK" << std::endl;
   std::cout << std::string(60, '=') << std::endl;
   
   vs2019_check_current_state();
   vs2017_check_current_state();
   
   std::cout << "\n=== Test Conclusions ===" << std::endl;
   std::cout << "If global state is shared:" << std::endl;
   std::cout << "- VS2017 and VS2019 should see the same locale" << std::endl;
   std::cout << "- Environment variables should be visible to both" << std::endl;
   std::cout << "- Timezone changes should affect both" << std::endl;
   std::cout << "\nIf global state is separate:" << std::endl;
   std::cout << "- Each CRT should maintain its own state" << std::endl;
   std::cout << "- Changes in one should not affect the other" << std::endl;
   
   return 0;
}

由于这些接口都是普通无参函数,所以声明为C导出风格还是C++风格都无所谓

 

接着在VS2019中引入编译链接也没什么大问题

测试结果如下

C:\Users\admin\Desktop\zxc\Debug>zxc
=== Global State Conflict Test ===
Testing CRT global state sharing between VS2017 and VS2019
 
============================================================
STEP 1: VS2019 Setting Initial Global State
============================================================
=== VS2019 Global State Test Started ===
=== VS2019 Setting Locale ===
VS2019: French locale number: 1234,56
VS2019: French date: lundi, 04 mai 2026
VS2019: Current locale: French_France.1252
 
=== VS2019 Setting Terminate Handler ===
VS2019: Terminate handler set
VS2019: Previous handler was: set
 
=== VS2019 Setting New Handler ===
VS2019: New handler set
VS2019: Previous new handler was: null
 
=== VS2019 Setting Environment ===
VS2019: _putenv result: 0
VS2019: VS2019_VAR = FromVS2019CRT
VS2019: SHARED_VAR = VS2019_Modified
 
=== VS2019 Setting Timezone ===
VS2019: Timezone set to EST
VS2019: Current time offset: 18000 seconds
VS2019: Daylight saving: Yes
 
=== VS2019 Global State Test Completed ===
 
=== VS2019 Checking Current State ===
VS2019: Current locale: French_France.1252
VS2019: VS2017_VAR = NULL
VS2019: SHARED_VAR = VS2019_Modified
VS2019: VS2019_VAR = FromVS2019CRT
VS2019: Number format test: 1234.56
 
============================================================
STEP 2: Calling VS2017 Library
============================================================
=== VS2017 Global State Test Started ===
=== VS2017 Setting Locale ===
VS2017: German locale number: 1234,56
VS2017: German date: Montag, 04 Mai 2026
VS2017: Current locale: German_Germany.1252
 
=== VS2017 Setting Terminate Handler ===
VS2017: Terminate handler set
VS2017: Previous handler was: set
 
=== VS2017 Setting New Handler ===
VS2017: New handler set
VS2017: Previous new handler was: null
 
=== VS2017 Setting Environment ===
VS2017: _putenv result: 0
VS2017: VS2017_VAR = FromVS2017CRT
VS2017: SHARED_VAR = VS2017_Setting
 
=== VS2017 Setting Timezone ===
VS2017: Timezone set to PST
VS2017: Current time offset: 28800 seconds
VS2017: Daylight saving: Yes
 
=== VS2017 Global State Test Completed ===
 
============================================================
STEP 3: VS2019 Checking State After VS2017 Call
============================================================
 
=== VS2019 Checking Current State ===
VS2019: Current locale: French_France.1252
VS2019: VS2017_VAR = NULL
VS2019: SHARED_VAR = VS2019_Modified
VS2019: VS2019_VAR = FromVS2019CRT
VS2019: Number format test: 1234.56
 
============================================================
STEP 4: VS2017 Checking Current State
============================================================
 
=== VS2017 Checking Current State ===
VS2017: Current locale: German_Germany.1252
VS2017: VS2017_VAR = FromVS2017CRT
VS2017: SHARED_VAR = VS2017_Setting
VS2017: VS2019_VAR = NULL
VS2017: Number format test: 1234.56
 
============================================================
STEP 5: VS2019 Modifying State Again
============================================================
VS2019: Set locale to English and added FINAL_VAR
 
============================================================
FINAL STATE CHECK
============================================================
 
=== VS2019 Checking Current State ===
VS2019: Current locale: English_United States.1252
VS2019: VS2017_VAR = NULL
VS2019: SHARED_VAR = VS2019_Modified
VS2019: VS2019_VAR = FromVS2019CRT
VS2019: Number format test: 1234.56
 
=== VS2017 Checking Current State ===
VS2017: Current locale: German_Germany.1252
VS2017: VS2017_VAR = FromVS2017CRT
VS2017: SHARED_VAR = VS2017_Setting
VS2017: VS2019_VAR = NULL
VS2017: Number format test: 1234.56
 
=== Test Conclusions ===
If global state is shared:
- VS2017 and VS2019 should see the same locale
- Environment variables should be visible to both
- Timezone changes should affect both
 
If global state is separate:
- Each CRT should maintain its own state
- Changes in one should not affect the other

 

给AI的检查报告: