مشاركة عبر


تحويل نوع المصدر

يصف هذا الموضوع كيفية تحويل عملية اليصدّر ما يلي أنواع:

  • الفئات

  • الواجهات

  • أنواع القيم

  • عمليات التعداد

بشكل عام، المحافظة على الأنواع التي تم تصديرها فإنها كانت ضمن تجميع، باستثناء مساحة الاسم المقترن بنفس الاسم مدارة اسم. على سبيل المثال، نوع A.B.IListفي ما يلي تعليمات برمجية تحويل نموذج إلى IListفي مكتبة النوع الذي تم تصديره. قد يشير عميل COM إلى نوع ك IListبدلاً من A.B.IList.

Namespace A
    Namespace B
        Interface IList
               …       
        End Interface
    End Namespace
End Namespace
namespace A {
    namespace B {
        interface IList {
               …
        }
    }
}

مع this approach, نوع names معin an تجميع can potentially collide because أنواع in different مساحات الاسم can have the same اسم. عند اكتشاف عملية التصدير تضارب، فهو يحتفظ بمساحة الاسم إلى إزالة ambiguities التسمية. يظهر نموذج تعليمات برمجية التالي مساحات أسماء الثاني بنفس اسم النوع.

Namespace A
    Namespace B
        Public Class LinkedList
            Implements IList
        End Class
      
        Public Interface IList
        End Interface 
    End Namespace
End Namespace

Namespace C
    Public Interface IList
    End Interface
End Namespace
namespace A {
    namespace B {
        public class LinkedList : IList {…}
        public interface IList {…}
    }
}
   namespace C {
       public interface IList {…}
}

تمثيل مكتبة النوع التالي بإظهار الدقة من كل اسم النوع. أيضا، منذ فترات زمنية غير صالحة في نوع أسماء المكتبة، يستبدل عملية تصدير كل فترة بواسطة تسطير أسفل السطر.

تمثيل مكتبة نوع

library Widgets 
{
    […]
    coclass LinkedList 
    {
        interface A_B_IList
    };

    […]
    interface A_B_IList {…};
    […]
    interface C_IList {…};
};

تقوم عملية التصدير أيضا تلقائياً بإنشاء معرّف برمجي (‏‏معرّف البرنامج) عن طريق دمج مساحة الاسم و اسم النوع. على سبيل المثال، ‏‏معرّف البرنامج التي تم إنشاؤها ل مدارة LinkedListفئة هو مبين في الأمثلة السابقة A.B.LinkedList.

ضم مساحة الاسم و اسم نوع يمكن أن ينتج ‏‏معرّف البرنامج غير صالح. ‏‏معرّف البرنامج تقتصر على أحرف 39 ويمكن أن تحتوي على أحرف علامات التنقيط لم غير ذلك من النقاط. لتجنب هذه الحدود، يمكنك تحديد ‏‏معرّف البرنامج في تعليمات برمجية المصدر بتطبيق ProgIdAttribute، بدلاً من السماح بالتصدير عملية لإنشاء معرّف لك.

الفئات

يصدّر عملية تحويل كل فئة عامة (وهذا يتجاهل السمة ComVisible (خطأ)) في تجميع إلى coclass في مكتبة نوع. زملاء المصدرة فئة لم يكن أي من الأساليب أو الخصائص؛ ومع ذلك، فهو يحتفظ اسم مدار فئة وتنفيذ الجميع الواجهات المطبقة بوضوح بواسطة مدار فئة.

ما يلي تعليمات برمجية يظهر المثال التعريف IShapeالواجهة و Circleفئة، والذي يقوم بتنفيذ IShape. تمثيل مكتبة نوع المحول يتبع مثال التعليمة البرمجية.

Public Interface IShape
    Sub Draw()
    Sub Move(x As Integer, y As Integer)
End Interface

Class Circle
    Implements IShape
    Sub Draw Implements IShape.Draw
    …    
    Sub Move(x As Integer, y As Integer) Implements IShape.Move
    …
    Sub Enlarge(x As Integer)
    …
End Class
public interface IShape {
    void Draw();
    void Move(int x, int y);
}
class Circle : IShape  {
    void Draw();
    void Move(int x, int y);
    void Enlarge(int x);
}

تمثيل مكتبة نوع

[ uuid(…), dual, odl, oleautomation ]
interface IShape : IDispatch {
    HRESULT Draw();
    HRESULT Move(int x, int y);
}

[ uuid(…) ]
coclass Circle {
    interface IShape;
}

يمكن تطبيق كل coclass الأخرى واجهة واحدة، تسمى فئة الواجهة، بالذي يصدّر يمكن لعملية توليد تلقائياً. الواجهة فئة الكشف عن الجميع الأساليب والخصائص متوفر في الفئة المدارة الأصلي، وبالتالي تمكين عملاء COM إلى الوصول إليها بواسطة الاتصال من خلال واجهة الفئة.

يمكنك تعيين محدد عالمي معرفاً فريداً (UUID) إلى الفئة بتطبيق GuidAttribute أعلى تعريف الفئة المدارة مباشرة. أثناء عملية تحويل، نقل عملية التصدير القيمة المقدمة إلى GuidAttribute إلى UUID في مكتبة النوع. Otherwise, the يصدّر عملية obtains UUIDs من a تجزئة that يتضمن the إكمال اسم of the فئة, including the مساحة الاسم. Using the كامل اسم ensures that a فئة مع a given اسم في a given مساحة الاسم دوماً generates the same UUID, و that الثاني فئات مع different أسماء ‏‏مطلقاً توليد the same UUID.

Abstract فئات و فئات without public, الافتراضي constructors are marked مع the noncreatable نوع مكتبة سمة. غير ذلك نوع مكتبة السمات that يطبق على أصناف مساعدة, such كـ licensed, مخفي, restricted, و عنصر تحكم are not التعيين.

الواجهات

تقوم عملية التصدير بتحويل الواجهات التي تتم إدارتها إلى واجهات COM بنفس أساليب وخصائص كـ الواجهة المدارة، ولكن التواقيع أسلوب يختلف شكل كبير.

واجهة الهويات

واجهات COM بتضمين معرّف واجهة (IID) إلى تمييز واجهة واحدة من آخر. يمكنك تعيين معرف ثابت إلى أي واجهة المدارة بتطبيق السمة GuidAttribute. إذا قمت بحذف هذه السمة و عدم تعيين معرف ثابت، عملية التصدير تلقائياً بتعيين واحد أثناء عملية تحويل. تشمل IID المعين من قبل وقت التشغيل & & اسم الواجهة (بما في ذلك مساحة الاسم) و توقيع كاملة لكافة الأنماط المعرفة في واجهة. بإعادة ترتيب طرق تشغيل الواجهة المدارة أو بتغيير وسيطة أسلوب و إرجاع أنواع، تقوم بتغيير معرف المعينة إلى تلك الواجهة. لا يؤثر تغيير اسم أسلوب على معرف.

الطريقة QueryInterface المطبقة بواسطة وقت التشغيل باستخدام، عملاء COM يمكن الحصول على واجهة الحاجة الثابتة معرف أو معرف المعين من قبل وقت التشغيل. لا يتم الدائمة IIDs التي تم إنشاؤها بواسطة وقت التشغيل ضمن ملفات التعريف الخاصة بالنوع.

أنواع الواجهات

إذا لم تقم بخلاف ذلك، تقوم عملية التصدير يحول مدارة على الجميع الواجهات إلى مزدوج واجهات في مكتبة نوع. واجهات الثنائي تمكين عملاء COM للاختيار بين مبكرا و ربط في وقت التشغيل.

يمكنك يطبق السمة InterfaceTypeAttribute إلى واجهة شكل انتقائي الإشارة إلى أن الواجهة يجب تصديرها كواجهة مزدوجة أو واجهة مشتقة من IUnknown واجهة الإرسال فقط (dispinterface). توسيع الجميع الواجهات التي تم تصديرها مباشرة من IUnknown أو IDispatch ، بغض النظر عن هيكلي للوراثة الخاصة بهم في تعليمات برمجية مُدارة.

يلي تعليمات برمجية يظهر المثال قيم اختيارية للتحكم في نوع الواجهة. بمجرد أن يتم تصديرها إلى مكتبة نوع، إنتاج هذه الخيارات نتائج المعروضة في تمثيل مكتبة النوع التالي من التعليمة البرمجية.

' Creates a Dual interface by default.
Public Interface InterfaceWithNoInterfaceType
    Sub test()
End Interface

' Creates a Dual interface explicitly.
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface InterfaceWithInterfaceIsDual
    Sub test()
End Interface

' Creates an IUnknown interface (not dispatch).
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface InterfaceWithInterfaceIsIUnknown
    Sub test()
End Interface

' Creates a Dispatch-only interface (dispinterface).
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface InterfaceWithInterfaceIsIDispatch
    Sub test()
End Interface
// Creates a Dual interface by default.
public interface InterfaceWithNoInterfaceType {
    void test();
}
// Creates a Dual interface explicitly.
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface InterfaceWithInterfaceIsDual {
    void test();
}
// Creates an IUnknown interface (not dispatch).
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface InterfaceWithInterfaceIsIUnknown {
    void test();
}
// Creates a Dispatch-only interface(dispinterface).
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface InterfaceWithInterfaceIsIDispatch {
    void test();
}

تمثيل مكتبة نوع

[ odl, uuid(…), dual, oleautomation ]
interface InterfaceWithNoInterfaceType : IDispatch {
    HRESULT test();
};
[ odl, uuid(…), dual, oleautomation ]
interface InterfaceWithInterfaceIsDual : IDispatch {
     HRESULT test();
};
[ odl, uuid(…), oleautomation ]
interface InterfaceWithInterfaceIsIUnknown : IUnknown {
     HRESULT test();
};
[ uuid(…) ]
dispinterface InterfaceWithInterfaceIsIDispatch {
     properties:
     methods:
         void test();
};

معظم الواجهات التي تم وضع علامة مع odl و oleautomation مكتبة السمات نوع أثناء عملية التصدير. (Dispinterfaces هي ‏‏ استثناء). مزدوج الواجهات يتم وضع علامة سمة مكتبة نوع مزدوج. واجهة مزدوجة مشتقة من الواجهة IDispatch ولكن أيضا الكشف عن فتحات vtable للأساليب الخاصة به.

واجهات الفئة

للحصول على وصف كامل لواجهة الفئة ونصائح الاستخدام، راجع التعريف "واجهة فئة" . The يصدّر عملية can توليد this واجهة automatically تشغيل behalf of a مدارة فئة without an واجهة بوضوح defined في مدارة تعليمات برمجية. COM clients cannot الوصول فئة وظائف directly.

The following تعليمات برمجية مثال shows a فئة الأساس و a الفئة المشتقة. لا هذا ولا ذاك فئة implements an explicit واجهة. The يصدّر عملية provides a فئة واجهة for كلاهما مدارة فئات.

Public Class BaseClassWithClassInterface
    Private Shared StaticPrivateField As Integer
    Private PrivateFld As Integer
   
    Private Property PrivateProp() As Integer
        Get
            Return 0
        End Get
        Set
        End Set
    End Property
   
    Private Sub PrivateMeth()
        Return
    End Sub 
    Friend Shared StaticInternalField As Integer
    Friend InternalFld As Integer
   
    Friend Property InternalProp() As Integer
        Get
            Return 0
        End Get
        Set
        End Set
    End Property
   
    Friend Sub InternalMeth()
        Return
    End Sub 
    Public Shared StaticPublicField As Integer
    Public PublicFld As Integer
   
    Public Property PublicProp() As Integer
        Get
            Return 0
        End Get
        Set
        End Set
    End Property
   
    Public Sub PublicMeth()
        Return
    End Sub
End Class
 
Public Class DerivedClassWithClassInterface
    Inherits BaseClassWithClassInterface
   
    Public Sub Test()
        Return
    End Sub
End Class
public class BaseClassWithClassInterface {
    private  static int  StaticPrivateField;
    private  int  PrivateFld;
    private  int  PrivateProp{get{return 0;} set{;}}
    private  void PrivateMeth() {return;}

    internal static int  StaticInternalField;
    internal int  InternalFld;
    internal int  InternalProp{get{return 0;} set{;}}
    internal void InternalMeth() {return;}

    public   static int  StaticPublicField;
    public   int  PublicFld;
    public   int  PublicProp{get{return 0;} set{;}}
    public   void PublicMeth() {return;}
}

public class DerivedClassWithClassInterface : BaseClassWithClassInterface {
    public void Test() {return;}
}

تمثيل مكتبة نوع

[odl,uuid(…), hidden, dual, nonextensible, oleautomation]
interface _BaseClassWithClassInterface : IDispatch {
     [id(00000000),propget]   HRESULT ToString([out, retval] BSTR* p);
     [id(0x60020001)]         HRESULT Equals([in] VARIANT obj, 
                                [out, retval] VARIANT_BOOL* p);
     [id(0x60020002)]         HRESULT GetHashCode([out,retval] long* p);
     [id(0x60020003)]         HRESULT GetType([out, retval] _Type** p);
     [id(0x60020004),propget] HRESULT PublicProp([out,retval] long* p);
     [id(0x60020004),propput] HRESULT PublicProp([in] long p);
     [id(0x60020006)]         HRESULT PublicMeth();
     [id(0x60020007),propget] HRESULT PublicFld([out, retval]long* p);
     [id(0x60020007),propput] HRESULT PublicFld([in] long p);
};
[odl,uuid(…), hidden, dual, nonextensible, oleautomation]
interface _DerivedClassWithClassInterface : IDispatch {
     [id(00000000),propget]   HRESULT ToString([out, retval] BSTR* p);
     [id(0x60020001)]         HRESULT Equals([in] VARIANT obj, 
                                [out, retval] VARIANT_BOOL* p);
     [id(0x60020002)]         HRESULT GetHashCode([out,retval] long* p);
     [id(0x60020003)]         HRESULT GetType([out, retval] _Type** p);
     [id(0x60020004),propget] HRESULT PublicProp([out,retval] long* p);
     [id(0x60020004),propput] HRESULT PublicProp([in] long p);
     [id(0x60020006)]         HRESULT PublicMeth();
     [id(0x60020007),propget] HRESULT PublicFld([out, retval]long* p);
     [id(0x60020007),propput] HRESULT PublicFld([in] long p);
     [id(0x60020008)]         HRESULT Test();
}

The exported فئة الواجهات have the following characteristics:

  • Each فئة واجهة retains the اسم of the مدارة فئة, but هو prefixed مع an تسطير سفلي. When an واجهة اسم conflicts مع a previously defined واجهة اسم, the جديد اسم هو appended مع an تسطير سفلي و an تزايدي رقم. For مثيل, the التالي متوفر اسم for _ClassWithClassInterface هو _ClassWithClassInterface_2.

  • The يصدّر عملية دوماً generates جديد واجهة identifiers (IID). You cannot بوضوح التعيين the IID of the فئة واجهة.

  • بواسطة الافتراضي, كلاهما فئة الواجهات derive من IDispatch الواجهات.

  • The الواجهات have ODL, dual, مخفي, nonextensible و oleautomation السمات.

  • كلاهما الواجهات have الجميع the الأعضاء عامة of its فئة الأساس (النظام.كائن).

  • They do لا يحتوي على the private أو internal الأعضاء of the فئة.

  • Each عضو هو automatically assigned a فريد DispId. The DispIds can be التعيين بوضوح بواسطة applying DispIdAttribute إلى the عضو of the فئة.

  • أسلوب signatures are transformed إلى return HRESULTs و have [خارج, retval] معلمات.

  • The خصائص و حقول are transformed في [propget], [propput], و [propputref].

الافتراضي واجهة

COM has the notion of a الافتراضي واجهة. الأعضاء of the الافتراضي واجهة are treated كـ the الأعضاء of the فئة بواسطة late-حدود languages مثل Visual أساسى. في the .NET Framework, there غير محقق need for a الافتراضي واجهة because فئات themselves can have الأعضاء. However, when exposing فئات إلى COM, فئات are much easier إلى استخدم if they have a الافتراضي واجهة.

When a مدارة فئة هو exported إلى a نوع مكتبة كـ a coclass, واحد واجهة هو typically identified كـ the الافتراضي واجهة for the فئة. If لا واجهة هو identified كـ the الافتراضي في the نوع مكتبة, most COM applications assume that the أول implemented واجهة هو the الافتراضي واجهة of that coclass.

كـ the following تعليمات برمجية مثال shows, the يصدّر عملية converts a مدارة فئة that has لا فئة واجهة و marks the أول implemented واجهة كـ the الافتراضي في the exported نوع مكتبة. The نوع مكتبة representation of the محول فئة follows the تعليمات برمجية مثال.

<ClassInterface(ClassInterfaceType.None)> _
Public Class ClassWithNoClassInterface
    Implements IExplicit
    Implements IAnother
    Sub M()
    …
End Class
[ClassInterface(ClassInterfaceType.None)]
public class ClassWithNoClassInterface : IExplicit, IAnother {
    void M();   
}

تمثيل مكتبة نوع

coclass ClassWithNoClassInterface {
    [default] IExplicit; 
    IAnother;
}

تقوم عملية التصدير بوضع علامة واجهة clكـs دائماً كـ الواجهة الافتراضية ل clكـs، بغض النظر عن أي واجهة غير ذلك بتنفيذ clكـs وضوح. يلي مثال يظهر فئتين محددتين.

<ClassInterface(ClassInterfaceType.AutoDispatch)> _
Public Class ClassWithAutoDispatch
    Implements IAnother
    Sub M()
    …
End Class 
 
<ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class ClassWithAutoDual
    Implements IAnother
    Sub M()
    …
End Class
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class ClassWithAutoDispatch : IExplicit, IAnother {
    void M();   
}

[ClassInterface(ClassInterfaceType.AutoDual)]
public class ClassWithAutoDual : IExplicit, IAnother {
    void M();   
}

تمثيل مكتبة نوع

// ClassWithAutoDispatch: IDispatch
coclass ClassWithAutoDispatch {
    [default] _ClassWithAutoDispatch;
    interface _Object;
    IExplicit;
    IAnother;
}
interface _ClassWithAutoDual {…}

coclass ClassWithAutoDual {
    [default] _ClassWithAutoDual; 
    IExplicit;
    IAnother;
}

أنواع القيم

يتم تصدير أنواع القيم (أنواع توسيع من النظام.القيمة) إلى اكتب المكتبات كبنية النمط C بتعريف نوع. تخطيط بنية الأعضاء هو يتم التحكم فيها بواسطة StructLayoutAttributeالسمة، التي هو تطبيقها على نوع. يتم تصدير حقول نوع القيمة فقط. إذا كان نوع القيمة وظائف، فهي غير قابلة للوصول من COM.

فعلى سبيل المثال:

[StructLayout(LayoutKind.Sequential)]
public struct Point {
    int x;
    int y;
    public void SetXY(int x, int y){ 
        this.x = x;
        this.y = y;
    }
};

يتم تصدير نوع القيمة يؤشر إلى COM كـ typedef يؤشر، كـ هو موضح في المثال التالي:

typedef 
[uuid(…)]
struct tagPoint {
    short x;
    short y;
} Point;

لاحظ أن عملية تحويل بإزالة SetXY أسلوب من typedef.

عمليات التعداد

تقوم عملية التصدير بإضافة قائمة تعداد مدارة ل نوع تبديل المكتبات لقائمة تعداد بأسماء الأعضاء لضمان تسمية العضو الفريد. للتأكد من أن كل اسم العضو هو Tlbexp.exe فريداً، بدء تسطير أسفل السطر إلى اسم قائمة التعداد لكل عضو من أعضاء أثناء عملية التصدير. البسيطة التالية على سبيل المثال، قائمة تعداد ينتج عن التعيين من تمثيلات مكتبة النوع.

Enum DaysOfWeek {
    Sunday = 0;
    Monday;
    Tuesday;
    …
};

تمثيل مكتبة نوع

enum DaysOfWeek {
    DaysOfWeek_Sunday = 0;
    DaysOfWeek_Monday;
    DaysOfWeek_Tuesday;
    …
};

وقت التشغيل نطاقات الأعضاء التعداد المدارة إلى التعداد التي تنتمي إليها. على سبيل المثال، الجميع المراجع إلى Sundayفي DaysOfWeekقائمة تعداد، وهو موضح في المثال السابق، يجب أن يكون مؤهلاً مع DaysOfWeek. لا يمكنك مرجع Sundayبدلاً من DaysOfWeek.Sunday. العضو الفريد تسمية هو مطلبا التعدادات COM.

راجع أيضًا:

المبادئ

تحويل تجميع الذي تم تصديره

تحويل وحدة نمطية? التي تم تصديرها

تحويل العضو الذي تم تصديره

تحويل المعلمات التي تم تصديرها

موارد أخرى

تجميع إلى نوع المهمة الموجزة لتحويل مكتبة