2011-10-23 20 views
5

Tôi đang viết một ứng dụng Delphi 2010. Nó có nhiều tập tin, hai trong số đó được gọi là Utils_ABS và Utils_MAT. Tôi đã tạo ra một loại bản ghi mà cả hai tập tin cần phải hiểu, vì vậy tôi đặt nó trong tập tin riêng của nó, được gọi là TypeDefs.inc.Tại sao tôi nhận được lỗi "loại không tương thích" ngay cả khi tôi đã thực hiện định nghĩa bản ghi có sẵn cho tất cả các đơn vị?

Ở đầu cả Utils_MAT và Utils_ABS, tôi có BAO GỒM TypeDefs.inc.

unit Utils_ABS; 

interface 

{$WARNINGS ON} 
{$HINTS ON} 
{$WARN UNIT_PLATFORM OFF} 
{$WARN SYMBOL_PLATFORM OFF} 

uses 
Windows, Messages, ... Utils, Analysis, UserFeedback, Utils_MAT; 

{$I TypeDefs.inc}  // Include TypeDefs that are used multiple places 

procedure ABS_Load; 
... 

Utils_MAT trông rất giống nhau, đặc biệt là liên quan đến {$I TypeDefs.inc}.

Các mục quan trọng là cả hai tập tin tham chiếu đến một tập tin thứ ba, TypeDefs.inc, như là một BAO GỒM NHỮNG SỰ, trong đó có định nghĩa của một RECORD:

type 
TTableAttrType = Record 
tabIOT: Boolean; // Is table an IOT 
... 
end; 

Không có gì khác chỉ là định nghĩa một kỷ lục này trong này tập tin.

Vấn đề là khi tôi biên dịch, tôi nhận được lỗi sau:

[DCC Error] Utils_ABS.pas(212): E2010 Incompatible types: 'Utils_ABS.TTableAttrType' and 'Utils_MAT.TTableAttrType'

Tôi hoàn toàn bối rối. Làm thế nào họ có thể là loại không tương thích nếu chúng đến từ cùng một định nghĩa? Không phải là bản sao của định nghĩa, nhưng theo nghĩa đen là cùng một định nghĩa.

Tôi đã kiểm tra tất cả mã nguồn của mình và bản ghi TTableAttrType này không được xác định ở bất kỳ nơi nào khác.

Tôi đã cố gắng nhận xét $ INCLUDE và mã hóa cứng định nghĩa của bản ghi thành cả Utils_ABS và Utils_MAT, nhưng tôi vẫn gặp lỗi tương tự.

Làm cách nào để nhận được lỗi này? Làm cách nào để xác định cấu trúc bản ghi ở một nơi và có nhiều tệp truy cập vào cấu trúc đó?

Trả lời

11

Bằng cách bao gồm định nghĩa như thế này, bạn đang xác định loại trong cả hai đơn vị. Vì Pascal (và mở rộng Delphi) sử dụng một số nominative type system, chứ không phải là structural type system, hai kiểu không giống nhau - chúng có các tên khác nhau, như được hiển thị trong thông báo lỗi.

Đặt định nghĩa TTableAttrType trong một đơn vị riêng biệt và ném đơn vị mới đó vào mệnh đề sử dụng của phần giao diện trong hai đơn vị khác. Sau đó, loại sẽ chỉ được xác định sau khi và bạn sẽ không còn có loại không tương thích nữa.

+0

Đó là nó. Nhiều THANKS! – user1009073

0

Mặc dù giải thích @ Michael là đúng, có một số điều quan trọng cần được thêm vào câu trả lời này.

Mặc dù có vẻ tương tự như {$INCLUDE ...} chỉ thị và mệnh đề Uses hoạt động hoàn toàn khác nhau. {$INCLUDE} nhập nguồn (như trong, đọc từ và sau đó dán vào) từ đơn vị được chỉ định vào đơn vị người gọi trong khi mệnh đề Uses biên dịch đơn vị được chỉ định và sau đó sử dụng nhị phân đã biên dịch (dcu). Vì vậy, khi bạn sử dụng {$ INCLUDE}, bạn không thực sự chia sẻ điều tương tự nhưng sao chép nó thay thế. Không quan trọng tên và cấu trúc của chúng là giống nhau, chúng là các thực thể hoàn toàn khác nhau đối với trình biên dịch. Khi sử dụng một đối tượng biên dịch, mặt khác, bạn đang đề cập đến cùng một thực thể chia sẻ.