Không khớp được phát hiện cho 'RuntimeLibrary'


114

Tôi đã tải xuống và giải nén Crypto ++ trong C: \ cryptopp. Tôi đã sử dụng Visual Studio Express 2012 để xây dựng tất cả các dự án bên trong (theo hướng dẫn trong readme) và mọi thứ đã được xây dựng thành công. Sau đó, tôi thực hiện một dự án thử nghiệm trong một số thư mục khác và thêm cryptolib làm phụ thuộc. Sau đó, tôi đã thêm đường dẫn bao gồm để tôi có thể dễ dàng bao gồm tất cả các tiêu đề. Khi tôi cố gắng biên dịch, tôi gặp lỗi về các ký hiệu chưa được giải quyết.

Để khắc phục điều đó, tôi đã thêm C:\cryptopp\Win32\Output\Debug\cryptlib.libliên kết các phần phụ thuộc bổ sung. Bây giờ tôi gặp lỗi này:

Error   1   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cryptlib.obj)    CryptoTest
Error   2   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(iterhash.obj)    CryptoTest
Error   3   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(sha.obj) CryptoTest
Error   4   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(pch.obj) CryptoTest
Error   5   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(misc.obj)    CryptoTest
Error   6   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(queue.obj)   CryptoTest
Error   7   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(algparam.obj)    CryptoTest
Error   8   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(filters.obj) CryptoTest
Error   9   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(fips140.obj) CryptoTest
Error   10  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cpu.obj) CryptoTest
Error   11  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(mqueue.obj)  CryptoTest

Tôi cũng nhận được:

Error   12  error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   13  error LNK2005: "public: __thiscall std::_Container_base12::~_Container_base12(void)" (??1_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   14  error LNK2005: "public: void __thiscall std::_Container_base12::_Orphan_all(void)" (?_Orphan_all@_Container_base12@std@@QAEXXZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   15  error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) already defined in cryptlib.lib(iterhash.obj) C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Warning 16  warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\LINK  CryptoTest
Error   17  error LNK1169: one or more multiply defined symbols found   C:\Data\Work\C++ VS\CryptoTest\Debug\CryptoTest.exe 1   1   CryptoTest

Mã tôi đã cố gắng biên dịch rất đơn giản (tôi lấy mã này từ một trang web khác):

#include <iostream>
#include <string>
#include "sha.h"
#include "hex.h"
using namespace std;

string SHA256(string data) {
    byte const* pbData = (byte*) data.data();
    unsigned int nDataLen = data.size();
    byte abDigest[32];

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

    return string((char*)abDigest);
}

int main(void) {

    return 0;
}

Bất kỳ ý tưởng làm thế nào để sửa lỗi này? Tôi thực sự chỉ cần SHA-256 ngay bây giờ, không có gì khác. Tôi đang sử dụng Windows 7 64 bit và tôi đã tải xuống VS C ++ hôm nay, vì vậy nó phải là phiên bản mới nhất.



1
Tôi đã đặt thư viện thời gian chạy dự án của mình thành Gỡ lỗi đa luồng (đó là cài đặt được sử dụng trong tiền điện tử ++) và bây giờ nó biên dịch! :) Cảm ơn bạn rất nhiều.
Momonga

Sự cố xảy ra sớm hơn nhiều khi bạn chạy VCUpgrade. Bạn đang thấy các triệu chứng của lỗi VCUpgrade đã được báo cáo là Thành công với bạn.
jww

Câu trả lời:


233

(Điều này đã được trả lời trong các bình luận, nhưng vì nó thiếu câu trả lời thực tế , tôi đang viết điều này.)

Sự cố này phát sinh trong các phiên bản mới hơn của Visual C ++ (các phiên bản cũ hơn thường chỉ liên kết âm thầm chương trình và nó sẽ bị lỗi và cháy khi chạy.) Điều đó có nghĩa là một số thư viện bạn đang liên kết với chương trình của mình (hoặc thậm chí một số nguồn tệp bên trong chính chương trình của bạn) đang sử dụng các phiên bản khác nhau của CRT (thư viện C RunTime.)

Để sửa lỗi này, bạn cần phải truy cập Project Properties(và / hoặc của những thư viện bạn đang sử dụng,) rồi vào C/C++, sau đó Code Generation, và kiểm tra giá trị của Runtime Library; điều này phải hoàn toàn giống nhau cho tất cả các tệp và thư viện mà bạn đang liên kết với nhau. (Các quy tắc được nới lỏng hơn một chút đối với việc liên kết với các tệp DLL, nhưng tôi sẽ không đi sâu vào "lý do tại sao" và chi tiết hơn ở đây.)

Hiện có bốn tùy chọn cho cài đặt này:

  1. Gỡ lỗi đa luồng
  2. DLL gỡ lỗi đa luồng
  3. Bản phát hành đa luồng
  4. DLL phát hành đa luồng

Vấn đề cụ thể của bạn dường như xuất phát từ việc bạn liên kết thư viện được xây dựng với "Gỡ lỗi đa luồng" (tức là CRT gỡ lỗi đa luồng tĩnh) với một chương trình đang được xây dựng bằng cách sử dụng cài đặt " Gỡ lỗi đa luồng DLL " (tức là CRT gỡ lỗi đa luồng động.) Bạn nên thay đổi cài đặt này trong thư viện hoặc trong chương trình của bạn. Hiện tại, tôi khuyên bạn nên thay đổi điều này trong chương trình của bạn.

Lưu ý rằng vì các dự án Visual Studio sử dụng các tập hợp cài đặt dự án khác nhau để gỡ lỗi và phát hành bản dựng (và bản dựng 32/64-bit), bạn nên đảm bảo cài đặt khớp trong tất cả các cấu hình dự án này.

Để biết thêm (một số) thông tin, bạn có thể xem những thông tin này (được liên kết từ nhận xét ở trên):

  1. Cảnh báo Công cụ liên kết LNK4098 trên MSDN
  2. / MD, / ML, / MT, / LD (Sử dụng Thư viện thời gian chạy) trên MSDN
  3. Lỗi xây dựng với VC11 Beta - trộn MTd lib với MDd exes không liên kết được trên Bugzilla @ Mozilla

CẬP NHẬT : (Đây là phản hồi cho một nhận xét yêu cầu lý do rằng điều này phải được cẩn thận.)

Nếu hai đoạn mã mà chúng tôi đang liên kết với nhau được tự liên kết chống lại và sử dụng thư viện tiêu chuẩn, sau đó các thư viện chuẩn phải giống nhau cho cả hai trong số họ, trừ khi lớn chăm sóc được lấy về làm thế nào hai mảnh mã của chúng ta tương tác với nhau và vượt qua xung quanh dữ liệu. Nói chung, tôi sẽ nói rằng đối với hầu hết các tình huống, chỉ cần sử dụng cùng một phiên bản chính xác của thời gian chạy thư viện tiêu chuẩn (liên quan đến gỡ lỗi / phát hành, chuỗi và rõ ràng là phiên bản của Visual C ++, trong số những thứ khác như gỡ lỗi trình lặp, v.v.)

Phần quan trọng nhất của vấn đề là: có cùng ý tưởng về kích thước của các đối tượng ở hai bên của một lệnh gọi hàm .

Hãy xem xét ví dụ rằng hai đoạn mã trên được gọi AB. A được biên dịch dựa trên một phiên bản của thư viện chuẩn và B dựa trên phiên bản khác. Theo quan điểm của A, một số đối tượng ngẫu nhiên mà một hàm tiêu chuẩn trả về cho nó (ví dụ: một khối bộ nhớ hoặc một trình lặp hoặc một FILEđối tượng hoặc bất cứ thứ gì) có một số kích thước và bố cục cụ thể (hãy nhớ rằng bố cục cấu trúc được xác định và cố định tại thời điểm biên dịch trong C / C ++.) Vì bất kỳ lý do nào trong số các lý do, ý tưởng của B về kích thước / bố cục của các đối tượng giống nhau là khác nhau (có thể là do thông tin gỡ lỗi bổ sung, sự phát triển tự nhiên của cấu trúc dữ liệu theo thời gian, v.v.)

Bây giờ, nếu A gọi thư viện chuẩn và lấy lại một đối tượng, sau đó chuyển đối tượng đó cho B và B chạm vào đối tượng đó theo bất kỳ cách nào, rất có thể B sẽ làm rối đối tượng đó (ví dụ: viết sai trường hoặc quá cuối của nó, v.v.)

Ở trên không phải là loại vấn đề duy nhất có thể xảy ra. Các đối tượng toàn cục hoặc tĩnh bên trong trong thư viện chuẩn cũng có thể gây ra sự cố. Và cũng có nhiều lớp vấn đề khó hiểu hơn.

Tất cả điều này trở nên kỳ lạ hơn ở một số khía cạnh khi sử dụng DLL (thư viện thời gian chạy động) thay vì libs (thư viện thời gian chạy tĩnh.)

Tình huống này có thể áp dụng cho bất kỳ thư viện nào được sử dụng bởi hai đoạn mã hoạt động cùng nhau, nhưng thư viện chuẩn được hầu hết các chương trình (nếu không phải là gần như tất cả) sử dụng và điều đó làm tăng khả năng xảy ra xung đột.

Những gì tôi đã mô tả rõ ràng là một phiên bản được giảm bớt và đơn giản hóa của mớ hỗn độn thực tế đang chờ bạn nếu bạn kết hợp các phiên bản thư viện. Tôi hy vọng rằng nó cung cấp cho bạn một ý tưởng về lý do tại sao bạn không nên làm điều đó!


Tôi la một chut Nhâm lân. Lỗi của OP là LNK2038 . Vì nó không xảy ra với tất cả các lib, tôi nghi ngờ Crypto ++ gặp một số cài đặt CRT khiến không thể kết hợp các hương vị CRT - thường đó chỉ là một cảnh báo (LNK4098) và bạn thể an toàn nếu bạn biết mình làm gì (không được khuyến nghị, nhưng có thể với những hạn chế, hãy xem ví dụ: stackoverflow.com/a/19944935/948581 ). Tuy nhiên, tôi không biết tại sao Crypto ++ lại bị ảnh hưởng theo cách này.

1
@Tibo: Đây không phải là các thư viện nhập cho các tệp DLL; Tôi tin rằng Crypto ++ thực sự đang được liên kết tĩnh với chương trình ở đây. Điều này có nghĩa là bất kỳ sự không phù hợp nào trong thư viện chuẩn được liên kết trong một mô-đun này với một mô-đun khác (có thể) đều vi phạm "Quy tắc một định nghĩa". Cái nào là xấu. Đây từng không phải là lỗi, vì trình liên kết thậm chí không thể phát hiện ra điều này (tên hàm / kiểu giống nhau, nhưng nội dung và định nghĩa của chúng khác nhau đáng kể) cho đến khi VC10 khi trình liên kết / thủ thư bắt đầu "gắn thẻ" các mô-đun nó cung cấp thêm thông tin về cấu hình của bản dựng ...
yzt

@Tibo: ... (tiếp tục từ bình luận trước) Ví dụ, hãy nhìn vào khối lỗi đầu tiên mà OP đang báo cáo. Trong đó, " RuntimeLibrary " là một thẻ trên cả thư viện Crypto ++ và tệp đối tượng cho chương trình của OP và giá trị của nó là " MDd_DynamicDebug " cho một trong số chúng và " MTd_StaticDebug " cho cái còn lại. Bằng cách này, trình liên kết đang cố gắng liên kết hai tệp đối tượng với nhau có thể phát hiện và báo cáo một nhóm lỗi hoàn toàn mới, cho rằng trình liên kết tạo ra các tệp đối tượng đó đã gắn thẻ chúng với bất kỳ thông tin liên quan nào, đặc biệt là bất kỳ cài đặt nào có khả năng vi phạm ODR.
yzt

Trong khi tôi hoàn toàn đồng ý với bạn, vẫn còn một khu vực bí ẩn ở đây. Đối với vấn đề của OP, tôi đoán anh ta đang bao gồm "dll.h" từ Crypto ++, và sau đó cố gắng liên kết với lib tĩnh thay vì thư viện nhập của DLL. Nhưng tôi đã nhìn thấy các lỗi chính xác cùng trên một máy tính, chứ không phải vào nhau (VS2013 sp4 cuối cùng -> lỗi, VS2013 cộng đồng SP5 -> ok) ...

1
@yzt Tôi đã tìm ra giải pháp. Thay vì sử dụng / ZW swicth, windows cung cấp cách sử dụng WinRT API thông qua COM bằng cách sử dụng trình bao bọc có tên WRL. Chỉ là việc không sử dụng / ZW làm cho việc viết mã hơi khó khăn vì nó ẩn các chi tiết triển khai COM, nhưng có thể sử dụng WinRT mà không cần / ZW.
Sahil Singh

3

Tôi đã tải xuống và giải nén Crypto ++ trong C: \ cryptopp. Tôi đã sử dụng Visual Studio Express 2012 để xây dựng tất cả các dự án bên trong (theo hướng dẫn trong readme) và mọi thứ đã được xây dựng thành công. Sau đó, tôi thực hiện một dự án thử nghiệm trong một số thư mục khác và thêm cryptolib làm phụ thuộc.

Việc chuyển đổi có thể không thành công. Điều duy nhất thành công là việc chạy VCUpgrade. Bản thân quá trình chuyển đổi thực tế không thành công nhưng bạn không biết cho đến khi bạn gặp các lỗi mà bạn đang thấy. Để biết một số chi tiết, hãy xem Visual Studio trên wiki Crypto ++.


Bất kỳ ý tưởng làm thế nào để sửa lỗi này?

Để giải quyết vấn đề của bạn, bạn nên tải xuống vs2010.zipnếu bạn muốn liên kết thời gian chạy C / C ++ tĩnh ( /MThoặc /MTd) hoặc vs2010-dynamic.zipnếu bạn muốn liên kết thời gian chạy C / C ++ động ( /MThoặc /MTd). Cả hai đều khắc phục các lỗi âm thầm, tiềm ẩn do VCUpgrade sản xuất.


vs2010.zip, vs2010-dynamic.zipvs2005-dynamic.zip được xây dựng từ các nguồn mới nhất GitHub . Kể từ khi viết bài này (ngày 1 tháng 6 năm 2016), đó thực sự là tiền Crypto ++ 5.6.4. Nếu bạn đang sử dụng các tệp ZIP có Crypto ++ cấp thấp hơn, như 5.6.2 hoặc 5.6.3, thì bạn sẽ gặp phải các vấn đề nhỏ.

Có hai vấn đề nhỏ mà tôi biết. Đầu tiên là đổi tên bench.cppthànhbench1.cpp . Lỗi của nó là:

  • C1083: Cannot open source file: 'bench1.cpp': No such file or directory
  • LNK2001: unresolved external symbol "void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

Cách khắc phục là (1) mở cryptest.vcxprojtrong notepad, tìm bench1.cppvà sau đó đổi tên nó thành bench.cpp. Hoặc (2) đổi tênbench.cpp thành bench1.cpptrên hệ thống tệp. Vui lòng không xóa tệp này.

Vấn đề thứ hai phức tạp hơn một chút vì nó là một mục tiêu di động. Các bản phát hành cấp thấp hơn, như 5.6.2 hoặc 5.6.3, thiếu các lớp mới nhất có sẵn trong GitHub . Các tệp lớp bị thiếu bao gồm HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4), v.v.

Cách khắc phục là loại bỏ các tệp nguồn bị thiếu khỏi tệp dự án Visual Studio vì chúng không tồn tại cho các bản phát hành cấp thấp hơn.

Một tùy chọn khác là thêm các tệp lớp bị thiếu từ các nguồn mới nhất, nhưng có thể có phức tạp. Ví dụ, nhiều trong những nguồn tinh tế phụ thuộc vào mới nhất config.h, cpu.hcpu.cpp. "Sự tinh tế" là bạn sẽ không nhận ra mình đang học kém.

Một ví dụ về lớp hoạt động kém là BLAKE2. config.hthêm thời gian biên dịch phát hiện ARM-32 và ARM-64. cpu.hcpu.cppthêm phát hiện lệnh ARM thời gian chạy, tùy thuộc vào phát hiện thời gian biên dịch. Nếu bạn thêm BLAKE2 mà không có các tệp khác, thì không có phát hiện nào xảy ra và bạn sẽ nhận được triển khai C / C ++ thẳng. Có thể bạn sẽ không nhận ra rằng mình đang bỏ lỡ cơ hội NEON, cơ hội này chạy khoảng 9 đến 12 chu kỳ mỗi byte so với 40 chu kỳ mỗi byte hoặc lâu hơn đối với vani C / C ++.


Tôi đã làm theo các hướng dẫn trong cryptopp wiki, tải xuống vs2010-dynamic.zip và dán nội dung của nó vào mã cryptopp563. Đã xây dựng và bị thiếu một số tệp nguồn. Không có vấn đề gì khi wiki nói rằng zip dành cho dự án mới nhất trên github và chỉ cần xóa mọi tệp bị thiếu. Đã xóa. Bây giờ dự án không xây dựng: 4 lỗi liên kết, một ví dụ: lỗi LNK2001: ký hiệu bên ngoài chưa được giải quyết "void __cdecl OutputResultOperations (char const *, char const *, bool, unsigned long, double)" (? OutputResultOperations @@ YAXPBD0_NKN @ Z)
Yaniv

Hóa ra có một băng ghế dự bị.cpp bị thiếu trong dự án. Nhưng ngay cả sau đó nó vẫn không biên dịch cho đến khi tôi áp dụng bản sửa lỗi này cho fiptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=split Tôi ước họ sẽ thực hiện một số thứ tự trong việc này, chẳng hạn như thêm tệp zip dự án thành git hoặc cái gì đó. Và có, tôi đã sơ ý nói rằng trình biên dịch của tôi là bản cập nhật VS2015 2. Tóm lại, hãy làm theo các gợi ý tôi đã viết và nó hoạt động.
Yaniv

@Yaniv - Đối với nhận xét đầu tiên, bạn đề xuất điều gì để những người dùng khác không gặp sự cố? Đối với nhận xét thứ hai, chúng tôi dự định thực hiện bản vá sau khi chúng tôi đã kiểm tra đầy đủ. Có điều gì chúng ta có thể làm trong lúc này không? (Tôi đã thêm thông tin bổ sung vào câu trả lời này, nhưng tôi muốn đảm bảo người dùng không gặp sự cố).
jww

Đầu tiên, cảm ơn rất nhiều vì đã làm điều này. Crypto ++ thực sự tuyệt vời. Về các vấn đề xây dựng, hãy cố gắng giữ cho các tệp dự án và sln cửa sổ tương thích với các tệp mới nhất trong dự án và vì những thay đổi này tất nhiên, các bản dựng cửa sổ này bằng cách nào đó phải được liên kết với cơ sở mã và thậm chí có thể nằm trên cây nguồn. Nếu quá nhiều, ít nhất hãy đảm bảo rằng tệp zip có môi trường xây dựng studio trực quan tương thích với bản phát hành chính thức ổn định hiện tại.
Yaniv

Về bản vá cho fiptest.cpp - có vẻ như có gì đó khác với VS2015, vì vậy tôi đoán bất kỳ ai muốn sử dụng VS2015 đều cần áp dụng bản vá này. Đó chỉ là một trường hợp khác trong khối #ifdef dường như xác định lệnh gọi lại gỡ lỗi phù hợp cho VS2015 và thực sự dễ dàng vá lỗi theo cách thủ công.
Yaniv

3

Tôi đã gặp sự cố này cùng với sự không khớp trong ITERATOR_DEBUG_LEVEL. Vì vấn đề chủ nhật-buổi tối sau khi tất cả đều có vẻ ổn và tốt để đi, tôi đã được đặt ra một thời gian. Làm việc trong IDE de VS2017 (Giải pháp Explorer) Gần đây, tôi đã thêm / sao chép tham chiếu tệp nguồn vào dự án của mình (ctrl-drag) từ một dự án khác. Xem xét thuộc tính-> C / C ++ / Bộ tiền xử lý - ở cấp tệp nguồn, không phải cấp dự án - tôi nhận thấy rằng trong cấu hình Phát hành _DEBUG đã được chỉ định thay vì NDEBUG cho tệp nguồn này. Đó là tất cả những thay đổi cần thiết để giải quyết vấn đề.


1

Vấn đề có thể được giải quyết bằng cách thêm CRT của msvcrtd.lib vào thư viện trình liên kết. Vì cryptlib.lib đã sử dụng phiên bản gỡ lỗi CRT.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.