2010-01-09 27 views
6

Tôi biết rằng COM cung cấp khả năng sử dụng lại ở cấp độ nhị phân trên các ngôn ngữ và ứng dụng. Tôi đọc rằng tất cả các thành phần được xây dựng cho COM phải tuân theo bố cục bộ nhớ tiêu chuẩn để không phụ thuộc vào ngôn ngữ.Tại sao COM (Mô hình đối tượng thành phần) không phụ thuộc vào ngôn ngữ?

Tôi không hiểu "bố cục bộ nhớ chuẩn" nghĩa là gì.

Điều gì làm cho ngôn ngữ độc lập với COM?

Trả lời

9

Đầu tiên, một số nền tảng kỹ thuật: Trình biên dịch C++ thường tạo ra một thứ được gọi là "vtable" cho bất kỳ lớp nào có chức năng ảo. Điều này về cơ bản là một bảng các con trỏ hàm. Vtable chứa một con trỏ hàm cho mọi phương thức ảo được thực hiện bởi một lớp.

Trong COM, giao diện cơ bản lớp cơ sở trừu tượng mà một cụ thành phần, ví dụ .:

class CSomeComponent : IUnknown, ISomeOtherInterface { ... }; 

Các vtable cho CSomeComponent sẽ bao gồm chức năng gợi ý cho tất cả các phương pháp quy định tại hai giao diện này.

struct __imaginary_vtable_for_CSomeComponent 
{ 
    // methods required by IUnknown 
    HRESULT (*QueryInterface)(const IID& iid, void** ppv); 
    ULONG (*AddRef)(); 
    ULONG (*Release)(); 
    // methods required by ISomeOtherInterface 
    void (*foo)(); 
    ... 
}; 

Bất kỳ đối tượng instantiated nào cũng có tham chiếu đến vtable loại động của nó. Đây là cách chương trình biết làm thế nào để gọi phương thức thích hợp trong trường hợp một phương pháp cơ bản được ghi đè trong một lớp học có nguồn gốc:

class Base 
{ 
public: 
    virtual void foo() { ... } 
} 

class Derived : public Base 
{ 
public: 
    virtual void foo() { ... } // overrides Base::foo() 
    virtual void bar() { ... } 
} 

... 

Base* X = new Derived; 
X->foo(); 

Dòng cuối cùng nên gọi Derived::foo. Điều này làm việc vì đối tượng X có tham chiếu đến vtable cho lớp Derived. Như đã nói, vtable giống như một danh sách các con trỏ hàm. Bây giờ, vtables có một bố cục cố định: Nếu lớp Derived kế thừa từ lớp Base, con trỏ hàm cho phương pháp foo sẽ có mặt tại vị trí tương đối giống nhau trong Derived 's vtable hơn trong Base' vtable s:

struct __imaginary_vtable_for_Base 
{ 
    void (*foo)(); 
}; 

// __imaginary_vtable_for_Base::foo = Base::foo 

struct __imaginary_vtable_for_Derived 
{ 
    void (*foo)(); 
    void (*bar)(); 
}; 

// __imaginary_vtable_for_Derived::foo = Derived::foo 

bây giờ, nếu trình biên dịch nhìn thấy một cái gì đó giống như X->foo(), nó biết rằng tất cả cho tất cả các lớp bắt nguồn từ Base, phương thức foo tương ứng với mục nhập đầu tiên trong vtable. Vì vậy, nó phát ra một cuộc gọi đến con trỏ hàm đầu tiên, trong trường hợp của X là một cuộc gọi đến Derived::foo.

Trả lời câu hỏi của bạn: Trình biên dịch chỉ có thể tạo thành phần COM nếu chúng tạo bố cục tương tự cho vtables mà đặc tả COM yêu cầu. vtables có thể được thực hiện theo nhiều cách khác nhau, đặc biệt là khi nói đến nhiều thừa kế (được yêu cầu với các thành phần COM). Việc tuân thủ định dạng vtable nhất định là cần thiết để khi bạn gọi phương thức của thành phần f, bạn sẽ thực sự gọi gọi phương thức f và không phải một số phương pháp khác g xảy ra ở vị trí f trong vtable của thành phần. Tôi cho rằng các trình biên dịch tuân thủ COM về cơ bản phải tạo ra các bố cục vtable giống như Microsoft Visual C++, vì công nghệ COM đã được Microsoft xác định.

P.S.: Xin lỗi vì đã quá kỹ thuật, tôi hy vọng các thông tin trên là một số cách sử dụng cho bạn.

+0

Bài đăng trên blog MSDN này (http://blogs.msdn.com/oldnewthing/archive/2004/02/05/68017.aspx) cũng có thể hữu ích. – stakx

+0

+1 để được giải thích rất hay. – Ashish

0

Bố cục bộ nhớ tiêu chuẩn có nghĩa là bố cục bộ nhớ được xác định (được chuẩn hóa) trong đặc tả COM, chứ không phải bất kỳ thứ tự mặc định nào sử dụng ngôn ngữ gọi hoặc xác định. Và chính xác là điều này làm cho ngôn ngữ độc lập! Mã trong một ngôn ngữ cụ thể gọi một đối tượng COM không phải quan tâm ngôn ngữ mà đối tượng COM đã được viết trong, về mặt hiểu biết cấu trúc của nó trong bộ nhớ.

0

Tôi nhớ COM là ngôn ngữ độc lập theo cách cấu trúc của nó được ghi lại và mở (?). Nhược điểm là cấu trúc là "nhị phân" và được gắn chặt với C/C++, điều này làm cho việc sử dụng các ngôn ngữ khác trở nên khó khăn. Tin tốt là rất nhiều ngôn ngữ (như Python) có giao diện C/C++, làm cho nó có thể (mô-đun Win32com Python) sử dụng từ các ngôn ngữ khác.

JSON là ngôn ngữ độc lập trong một cách mà nó không có bản đồ trực tiếp đến bất kỳ ngôn ngữ, mặc dù Python, Perl và Ruby (?) Là gần, nhưng nó là hầu như không thể sử dụng từ C/C++

Hy vọng điều này làm cho một số loại ý nghĩa

+4

-1 vì nhược điểm được khai báo là không chính xác và vì so sánh COM và JSON giống như so sánh động cơ với túi. – Fredrik

+0

Vâng, có và không, tôi sẽ cho rằng bạn có thể xem COM như một giao diện truyền tải cho một khách hàng để truy cập vào một "máy chủ", giống như một dịch vụ web. Nếu dịch vụ web là REST, nó sẽ thường sử dụng JSON. Vì vậy, theo quan điểm của tôi, việc so sánh không phải là quá xa vời ... – raindog

4

Don Box đã viết một lời giải thích tuyệt vời trong chương đầu tiên của cuốn sách Essential COM của mình. Bạn có thể đọc miễn phí here. Tôi khuyến khích điều đó.

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