2011-01-09 24 views
5

Tôi mới đến delphi. Tôi đã cố gắng để thêm các tập tin C Object trong dự án Delphi của tôi và liên kết chúng trực tiếp từ Delphi Hỗ trợ C Object Linking. Tôi nhận được nó làm việc khi tôi liên kết một tập tin Object duy nhất. Nhưng khi tôi cố gắng liên kết nhiều tệp đối tượng, tôi nhận được lỗi 'Không hài lòng về phía trước hoặc khai báo bên ngoài'. Tôi đã thử điều này trong Delphi 2007 cũng như XE.So tôi đang làm gì sai ở đây?Lỗi khi liên kết nhiều tệp đối tượng C trong Delphi 2007

Mã làm việc:

function a_function():Integer;cdecl; 

implementation 

{$Link 'a.obj'} 

function a_function():Integer;cdecl;external; 

end. 

Error Code:

function a_function():Integer;cdecl; 
function b_function();Integer;cdecl; 
function c_function();Integer;cdecl; 

implementation 

{$LINK 'a.obj'} 
{$LINK 'b.obj'} 
{$LINK 'c.obj'} 

function a_function():Integer;cdecl;external; 
function b_function();Integer;cdecl;external; 
function c_function();Integer;cdecl;external; 
end. 
+0

Đoán của tôi: "b_function()" hoặc "c_function()" không được tìm thấy trong bất kỳ tệp nào trong số ba tệp đối tượng. Bạn cho rằng vấn đề liên quan đến việc liên kết nhiều tệp đối tượng và bạn đã chứng minh rằng bạn có thể liên kết một tệp. Bạn đã thử liên kết, ví dụ: chỉ "b.obj" và chỉ nhập "b_function()"? –

+0

Có lẽ bài viết này của Rudy Velthuis có thể giúp: http://rvelthuis.de/articles/articles-cobjs.html – vcldeveloper

Trả lời

7

Ngoài ra, bài viết được liên kết bởi @vcldeveloper có giải thích tốt về một số vấn đề phổ biến. Bí quyết cung cấp các chức năng C RTL thiếu trong mã Pascal là tuyệt vời và nhanh hơn nhiều so với cố gắng liên kết trong các chức năng cần thiết dưới dạng tệp C hoặc thậm chí dưới dạng tệp .obj.

Tuy nhiên, tôi nghi ngờ rằng tôi biết những gì đang diễn ra ở đây. Tôi sử dụng phương pháp này nhưng trên thực tế có hơn 100 tệp .obj trong đơn vị. Tôi thấy rằng khi tôi thêm những cái mới, tôi nhận được cùng một lỗi liên kết như bạn làm. Cách tôi làm việc xung quanh việc này là thử đặt lại các hướng dẫn $ LINK của tôi. Tôi cố gắng thêm các tập tin obj mới từng người một và cuối cùng tôi đã có thể giải quyết vấn đề này.

Nếu tệp C của bạn hoàn toàn độc lập thì bạn có thể đặt từng tệp vào một đơn vị khác và trình liên kết sẽ xử lý điều đó. Tuy nhiên, tôi nghi ngờ đó là trường hợp và thực sự tôi nghi ngờ rằng nếu họ thực sự là độc lập thì vấn đề này sẽ không xảy ra. Ngoài ra, bạn nên có các lệnh $ LINK trong một đơn vị duy nhất để bất kỳ chức năng RTL nào cần được cung cấp có thể được cung cấp một lần và chỉ một lần (chúng cần xuất hiện trong cùng một đơn vị như hướng dẫn $ LINK).

kỳ quặc trong mối liên kết này đã có mặt ở Delphi 6 và hiện diện trong Delphi 2010.

EDIT 1: Việc thực hiện hiện nay đã hiểu ra nguyên với tôi rằng vấn đề này có lẽ là do Delphi sử dụng một trình biên dịch thông qua đơn . Tôi nghi ngờ rằng lỗi "tham chiếu bên ngoài bị thiếu" là do trình biên dịch xử lý các tệp .obj theo thứ tự mà chúng xuất hiện trong đơn vị.

Giả sử rằng a.obj xuất hiện trước b.obj nhưng a.obj gọi hàm trong b() b.obj. Trình biên dịch sẽ không biết nơi b() cư trú tại điểm mà nó cần phải sửa chữa các cuộc gọi chức năng. Khi tôi tìm thấy thời gian, tôi sẽ cố gắng và thử nghiệm nếu giả thuyết này là ít nhất là hợp lý!

Cuối cùng, một cách dễ dàng khác trong vấn đề là kết hợp a.c, b.c và c.c thành một tệp C duy nhất mà tôi tin rằng sẽ bỏ qua vấn đề này cho OP.

Chỉnh sửa 2: Tôi tìm thấy một câu hỏi Stack Overflow bao gồm đất này: stackoverflow.com/questions/3228127/why-does-the-order-of-linked-object-file-with-l-directive-matter

Sửa 3: Tôi đã tìm thấy một cách thực sự tuyệt vời để làm việc xung quanh vấn đề này.Mỗi lần trình biên dịch phàn nàn

[DCC Error] Unit1.pas(1): E2065 Unsatisfied forward or external declaration: '_a' 

bạn chỉ cần thêm, trong phần thi của đơn vị, một tuyên bố như vậy:

procedure _a; external; 

Nếu đó là một thói quen mà bạn muốn gọi từ Delphi sau đó bạn rõ ràng cần phải có được danh sách tham số, gọi quy ước vv chính xác. Nếu không, nếu nó là một nội bộ thường quy bên ngoài mã, thì bạn có thể bỏ qua danh sách tham số, gọi các quy ước, v.v.

Theo cách hiểu tốt nhất, đây là cách duy nhất để nhập hai đối tượng tham chiếu lẫn nhau một cách tròn. Tôi tin rằng việc tuyên bố một thủ tục bên ngoài theo cách này là giống như việc đưa ra một tuyên bố về phía trước. Sự khác biệt là việc triển khai được cung cấp bởi một đối tượng thay vì mã Pascal.

Tôi hiện đã có thể thêm một vài công cụ nữa vào kho vũ khí của mình - cảm ơn bạn đã đặt câu hỏi!

+0

Cảm ơn bạn rất nhiều. Tôi đoán các mối liên kết duy nhất vượt qua là vấn đề. Tôi đang liên kết hơn 30 đối tượng không đứng một mình. Vì vậy, tôi sẽ phải sắp xếp lại các tập tin Object của tôi hoặc đặt sau đó trong một tập tin duy nhất. – Ramnish

+0

@Ramnish Tôi muốn được nghe cách bạn tiếp tục. Về mặt đạo đức, tôi nghĩ rằng đó là trình biên dịch đơn lẻ hơn là mối liên kết và bản năng của tôi cho tôi biết đây là vấn đề trình biên dịch chứ không phải là vấn đề liên kết, nhưng tôi chỉ đoán ở đây! –

+0

@Ramnish Tôi đã tìm thấy một câu hỏi Stack Overflow khác bao gồm nền tảng này: http://stackoverflow.com/questions/3228127/why-does-the-order-of-linked-object-file-with-l-directive-matter –

0

cú pháp của bạn là tốt, nhưng cũng giống như Cosmin nói có khả năng là một cái gì đó là sai với b.obj, c.obj hoặc b_functionc_function.

Hãy thử liên kết chúng riêng lẻ trước tiên hoặc chỉnh sửa bài đăng của bạn để hiển thị thông báo đầu ra mã và liên kết thực tế nếu có thể.

Các vấn đề liên quan