2010-07-11 29 views
6

Tôi đang cố tạo một phụ trợ ngôn ngữ của tôi cho nền tảng .NET. Mặt trước và thông dịch viên được viết bằng Delphi. API không được quản lý chỉ cho phép định nghĩa kiểu nhưng không phát ra từ MSIL.Có những cách nào để tạo MSIL từ mã không được quản lý

Có cách nào để tạo MSIL từ mã không được quản lý? Nếu không sử dụng Reflection.Emit và sử dụng ILasm để đạt được điều này? Cảm ơn bạn.

Trả lời

5

Trình tạo mã .NET của Delphi phát ra IL dưới dạng bytecode trực tiếp vào bộ nhớ, giống như tạo mã x86, mặc dù có tiêu đề thích hợp, v.v. Tức là trình tạo mã phát trực tiếp byte, bảng ngoại lệ, v.v. . Nó không làm điều này với một API, mà là cách cũ: viết mã một byte tại một thời điểm.

Sau đó, trình liên kết tích hợp của Delphi hoạt động với IMetaDataEmit v.v. để tạo siêu dữ liệu và IMetaDataEmit::SetRVA để thông báo cho siêu dữ liệu nơi mã sẽ được đặt trong tệp thực thi. Siêu dữ liệu được sao chép với IMetaDataEmit::SaveToMemory và sau đó được sao chép vào PE mà trình liên kết đã xây dựng, với tiêu đề CLR được vá tương ứng để trỏ tới bắt đầu siêu dữ liệu.

Đó là rất nhiều mã, một số khó sử dụng, vì phần lớn nó được nối qua trình liên kết x86 hiện có của Delphi, những thứ như tối ưu hóa chi nhánh và loại bỏ mã không sử dụng (liên kết thông minh). cần thiết cho .NET.

Nếu chúng tôi làm lại tất cả, chúng tôi có thể tránh các API .NET để tạo siêu dữ liệu và tạo toàn bộ nội dung ngay từ thông số. Các API đã kết thúc thành một hộp đen để tối ưu hóa và thêm vào một số lượng đáng kể thời gian biên dịch.

+0

Cảm ơn, Barry. –

3

Từ không được quản lý mã? TBH, gợi ý tốt nhất mà tôi có là "sử dụng P/Invoke" hoặc "tìm ra ý nghĩa của nó và thực hiện lại nó".

Ngay cả khi bạn có thể tìm nội dung nào đó để chuyển mã không được quản lý và thậm chí nếu nó hoạt động - nó không chính xác sẽ tận dụng khung. Và nó không phải là chính xác 1: 1 giữa không được quản lý và quản lý.

+1

Tôi cần một API cho phép tôi phát trực tiếp MSIL (đọc từ Delphi gốc) bằng cách sử dụng marshaling không quản lý (Pinvoke, đảo ngược pinvoke, IJW, COM). Bạn có đề nghị tôi tạo PE Files không? –

2

Bạn đang gặp khó khăn. Các thư viện cơ sở hạ tầng biên dịch Irony và Common Compiler có sẵn tại Codeplex.com được đưa ra, chúng được nhắm tới các trình biên dịch được thực hiện trong mã được quản lý. Tùy chọn tiếp theo là sử dụng giao diện siêu dữ liệu không được quản lý, như IMetaDataAssemblyEmit, IMetaDataAssemblyImport, IMetaDataEmit2. Tuy nhiên, các giao diện COM này được khai báo trong tệp tiêu đề SDK cor.h, chỉ phù hợp để sử dụng bởi chương trình C/C++. Không có thư viện kiểu nào cho chúng. Ngắn từ việc sao chép cẩn thận các khai báo giao diện, bạn cần một số loại công cụ để chuyển đổi chúng thành các khai báo Delphi. Không chắc chắn nếu điều đó tồn tại.

+1

Tôi dịch (cor.h corhdr.h) thành tập tin pas bằng tay 2 ngày trước. Vì vậy, Unmanaged API có sẵn để kết thúc phía trước bản địa của trình biên dịch của tôi. Nhưng API không hỗ trợ cho việc phát sinh MSIL để thực hiện phương pháp. –

+0

ICeeGen đã lỗi thời. Tôi không biết về một sự thay thế. –

2

MSIL hoặc CIL về cơ bản là .Net tương đương với mã máy. Khi bạn phân tích một ngôn ngữ và dịch nó thành mã máy, những gì bạn có là một trình biên dịch . Các trình biên dịch ban đầu bằng bất kỳ ngôn ngữ nào thường sẽ tạo mã máy của chúng theo cách thủ công. Tức là, đối với mỗi loại lệnh hoặc biểu thức trong ngôn ngữ nguồn, hãy viết một "mẫu" của các hướng dẫn lắp ráp để dịch nó thành. Khi bạn làm việc thông qua biểu diễn trung gian của chương trình, hãy chọn mẫu tương ứng, điền vào các chi tiết chương trình cụ thể và phát ra CIL. Đối với một ngôn ngữ dựa trên ngăn xếp như CIL, sẽ khá dễ dàng để kết hợp các mẫu với nhau từ nhiều câu lệnh; ngăn xếp đầu ra của một câu lệnh là ngăn xếp đầu vào tiếp theo.

Bạn sẽ muốn tự làm quen với CIL instruction set.

Thực tế là trình biên dịch của bạn không được quản lý mã không quan trọng. Bạn có thể tạo văn bản CIL từ bất kỳ loại chương trình nào bạn muốn. Khi nó đã sẵn sàng, hãy gửi nó qua ilasm để tạo một hội đồng từ nó.

+0

Rob, tôi đã đọc ECMA335 cũng như "Expert .NET 2.0" của Serge Lidin cách đây 3 năm. (Vì vậy, ilAsm chỉ là một người bạn khác của tôi). Rob, bạn có thể hỏi Barry Kelly hoặc có thể là Kẻ phản đối cách họ giải quyết vấn đề này không. Hoặc có thể tất cả họ đều sử dụng chế độ hỗn hợp C++. –

+0

Trình biên dịch lăng kính được xây dựng với Prism và là một ứng dụng .NET 100%. –

+0

Cảm ơn bạn, Robert. –

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