Lỗi biên dịch MFC do nền tảng windows #defines. Đấu tranh để chẩn đoán lý do.

lập trình


Tôi đang sử dụng Visual Studio 2022 / C++ / MFC mới nhất, Windows SDK 10.0, Bộ công cụ nền tảng 10.0 (phiên bản cài đặt mới nhất), Tiêu chuẩn ngôn ngữ C++ ISO C++ 17 Tiêu chuẩn và bản dựng 64 bit.

Tôi đã bắt đầu với mẫu MDI tiêu chuẩn, thêm một số nội dung (điều khiển chỉnh sửa Scintilla, yêu cầu >= ISO C++ 17) và được biên dịch thành công.

Bây giờ tôi đang tích hợp mã nguồn hiện có từ quá trình phát triển trước đó (được biên dịch theo ISO C++ 14, nhưng đó có thể không phải là lời giải thích cho những gì tôi sắp mô tả).

Quá trình biên dịch của tôi hiện không thành công với các lỗi sau:

Error	C1189	#error:  CTaskDialog is not supported on Windows versions prior to Vista.	Visual SQL Studio	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\atlmfc\include\afxtaskdialog.h	18		

… Và

Error	C2664	'INT getaddrinfo(PCSTR,PCSTR,const ADDRINFOA *,PADDRINFOA *)': cannot convert argument 1 from 'LPCTSTR' to 'PCSTR'	Visual SQL Studio	C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\atlmfc\include\atlsocket.h	163		

Vì vậy, không có trong mã của tôi. Trong cả hai trường hợp, đều có quá trình biên dịch có điều kiện dựa trên phiên bản Windows #defines. Ví dụ: đối với lỗi đầu tiên, mã là:

#if (NTDDI_VERSION < NTDDI_VISTA) // min Windows Vista required
#error CTaskDialog is not supported on Windows versions prior to Vista.
#endif

Giải thích của tôi về điều này là trình biên dịch thấy giá trị của NTDDI_VERSION nhỏ hơn giá trị của NTDDI_VISTA và do đó gây ra lỗi.

NHƯNG, tôi chỉ sử dụng tất cả các giá trị mặc định được tạo bởi mẫu dự án cho pch.h, framework.h và targetver.h, điều này (nếu hiểu biết của tôi là chính xác) tương đương với

#include <SDKDDKVer.h>

.

Vì vậy, tôi đang suy nghĩ về lời giải thích hoặc cách chữa trị cho vấn đề này. Tôi chắc chắn không định nghĩa lại phiên bản Windows #defines ở nơi khác. Tuy nhiên, tôi nghĩ

NTDDI_VERSION

thực sự không được xác định tại điểm trong tệp tiêu đề nơi áp dụng thử nghiệm phiên bản, bởi vì chỉnh sửa này (tôi biết) khiến quá trình biên dịch thành công:

#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_WIN10

#if (NTDDI_VERSION < NTDDI_VISTA) // min Windows Vista required
#error CTaskDialog is not supported on Windows versions prior to Vista.
#endif

Chỉnh sửa rõ ràng AfxTaskDialog.h không phải là một giải pháp có thể chấp nhận được, vì vậy tôi vô cùng biết ơn nếu có bất kỳ đề xuất nào về cách chẩn đoán/giải quyết vấn đề này.

Tóm tắt định nghĩa framework/nền tảng

pch.h – #include “framework.h” làm dòng đầu tiên.
framework.h – #include “targetver.h” làm dòng đầu tiên
targetver.h – #include làm dòng đầu tiên

Những gì tôi đã thử:

Tôi đã #xác định rõ ràng NTDDI_VERSION trong pch.h và/hoặc framework.h và/hoặc targetver.h. Tôi đã buộc NTDDI_VERSION vượt qua bài kiểm tra #if (NTDDI_VERSION < NTDDI_VISTA) bằng mã hóa cứng NTDDI_VERSION (hoạt động nhưng không phải là giải pháp khả thi).

Giải pháp 1

Để tìm ra vấn đề đầu tiên trong cài đặt trình biên dịch trên tab Nâng cao C/C++, hãy chọn “hiển thị bao gồm” và nó hiển thị trong quá trình xây dựng trình tự bao gồm – theo cách này bạn có thể tìm thấy là NTDDI_VERSION được xác định trước tệp bạn quan tâm hoặc có thể nó không được xác định ở đâu đó. Ngoài ra, hãy đảm bảo SDKDDKVer.h được đưa vào trước – hãy thử đặt nó đầu tiên trong tệp tiêu đề được biên dịch trước của bạn (pch.h)
Lỗi thứ hai xảy ra do TCHAR được xác định là ký tự UNICODE nhưng hàm lại mong đợi CHAR. Thay đổi cài đặt thành MBCS thay vì UNICODE (tab Chung trong thuộc tính và chọn giá trị “Bộ ký tự”) – điều này có thể hữu ích nếu đó không phải là mã của bạn, nếu không, bạn có thể tìm ra tham số được truyền trong mã.

Hy vọng điều này giúp đỡ.

Trân trọng,
Châm ngôn.

コメント

タイトルとURLをコピーしました