ما هو COM - لماذا لا يزال تصميم Windows COM يبدو جميلاً حتى اليوم

· آخر تحديث: · · COM, ActiveX, تطوير Windows

سجل التعديلات (3 تحديثات، آخر تحديث 3 Sep، 2026)

سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.

أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240793)
أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621303)

هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.

小村 豪 (2026). ما هو COM - لماذا لا يزال تصميم Windows COM يبدو جميلاً حتى اليوم. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621303 https://comcomponent.com/ar/blog/2026/01/25/001-why-com-is-beautiful/

DOI (أحدث نسخة)
10.5281/zenodo.21621303
DOI (هذه النسخة)
10.5281/zenodo.22279674

ما هو COM؟

COM (Component Object Model) هو «عقد ثنائي» تتواصل به المكوّنات فيما بينها على Windows. آلية تتواصل عبر عقد صارم اسمه الواجهة، متجاوزة اختلافات اللغات والمترجمات، وفي أسسه فكرة تصميم تقول: «لا تبرمج مقابل التنفيذ، بل مقابل العقد».

في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 23، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle

العناصر الثلاثة المهمّة في COM

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

1. تصميم يتمحور حول الواجهة

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

2. التعريف عبر GUID (CLSID / IID)

يُمنح كلّ مكوّن وكلّ واجهة معرّفاً فريداً عالمياً (GUID)، لذلك لا يقع تصادم الأسماء أصلاً.

3. IUnknown

الواجهة الأساسية التي ترثها كلّ واجهات COM. تقدّم الوظائف الثلاث التالية.

الدالة الدور
QueryInterface السؤال عمّا إذا كان الكائن يحمل واجهة أخرى
AddRef زيادة عدّاد المراجع
Release إنقاص عدّاد المراجع (وعند الصفر يدمّر الكائن نفسه)

عندما تجتمع هذه العناصر الثلاثة، لا يبقى بين المستدعي والتنفيذ سوى «واجهة معرّفة بـ GUID وترتيب دوالّها ثابت». لا تظهر اللغة ولا المترجم في هذا العقد.

التنفيذ ── اللغة غير مقيّدةجهة الاستدعاء ── اللغة غير مقيّدةمكوّن مكتوب بـ C++مكوّن مكتوب بـ C#تطبيق C++تطبيق C#VBA / Python وغيرهماالعقد (الجزء المثبت ثنائياً)· يحدّد IID (GUID) أيّ عقد هو بشكل فريد· ترتيب يبدأ بدوال IUnknown الثلاث· نوع الوسائط والقيمة المعادة وcalling convention لكلّ دالة

الشكل 1: العقد الثنائي في COM. لا تظهر لغة المستدعي ولا لغة التنفيذ في العقد، لذلك يمكن استبدال أيّ طرف دون إعادة بناء الطرف الآخر.

«البرمجة مقابل العقد» كما تظهر في الشيفرة

يصعب فهم ذلك بالنصّ وحده، فنحوّله إلى حدّ أدنى من الشيفرة. المثال يستخدم مكوّن جمع بسيط ICalcService دون أيّ معرفة بتنفيذه.

نبدأ من C++ (COM خام). تعريف ICalcService المكتوب هنا هو العقد نفسه. لا يظهر في شيفرة المستدعي إن كان التنفيذ مكتوباً بـ C++ أو بـ C#.

#include <objbase.h>

// تعريف العقد. عادةً تُولَّد ترويسة بهذا الشكل من IDL
// يرث IUnknown لذا يحمل QueryInterface / AddRef / Release حتماً
struct __declspec(uuid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001"))
ICalcService : public IUnknown
{
    virtual HRESULT STDMETHODCALLTYPE Add(int a, int b, int* result) = 0;
};

// عقد موسَّع أُضيف لاحقاً. GUID مختلف
struct __declspec(uuid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B002"))
ICalcServiceEx : public ICalcService
{
    virtual HRESULT STDMETHODCALLTYPE Multiply(int a, int b, int* result) = 0;
};

// CLSID مكوّن التنفيذ. عادةً يُعرَّف في ترويسة مولَّدة من IDL
static const CLSID CLSID_CalcService =
    { 0x1C9B6F4D, 0x1E9A, 0x4E61, { 0x9A, 0x4F, 0x6A, 0x0F, 0x1D, 0x2D, 0x9A, 0x11 } };

// جهة الاستدعاء
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) { return hr; }

ICalcService* calc = nullptr;
hr = CoCreateInstance(CLSID_CalcService, nullptr, CLSCTX_ALL,
                      __uuidof(ICalcService), reinterpret_cast<void**>(&calc));
// المؤشّر العائد هنا نُفِّذ عليه AddRef (عدّ المراجع = 1)

if (SUCCEEDED(hr))
{
    int sum = 0;
    hr = calc->Add(1, 2, &sum);          // يُستدعى دون معرفة التنفيذ

    // السؤال وقت التشغيل «هل يحمل العقد الموسَّع أيضاً» = تنفيذ يتعايش مع الإصدارات
    ICalcServiceEx* calcEx = nullptr;
    if (SUCCEEDED(calc->QueryInterface(__uuidof(ICalcServiceEx),
                                       reinterpret_cast<void**>(&calcEx))))
    {
        // لا نصل هنا إلا إذا كان المكوّن الإصدار الجديد
        calcEx->Release();               // من استلم المؤشّر يعيده
    }
    // إن لم يحمله يُعاد E_NOINTERFACE فقط، ويستمرّ الإصدار القديم في العمل

    calc->Release();                     // يصل عدّ المراجع إلى 0 فيُدمَّر
}
CoUninitialize();

مواضع القراءة ثلاثة.

  • نادراً ما تكتب AddRef بنفسك. كلّ من CoCreateInstance وQueryInterface يكون قد نفّذ AddRef على المؤشّر الذي يعيده. المبدأ إذاً: «من استلم المؤشّر يستدعي Release». لا تستدعي AddRef صراحة إلا عندما تبدأ بالاحتفاظ بالمؤشّر نفسه في موضع ثانٍ.
  • فشل QueryInterface ليس حالة شاذّة. «لا أحمل هذا العقد» (E_NOINTERFACE) جواب سليم، وهو ما يتيح «إضافة وظيفة جديدة دون كسر المكوّن القديم».
  • كلّ قيمة معادة هي HRESULT. إعادة النجاح والفشل بقيمة معادة لا باستثناء ترتيب لازم لعبور اللغات. طريقة رمي الاستثناءات تختلف من لغة إلى لغة، أمّا قيمة صحيحة فيفهمها الجميع.
مبدأ عدّ المراجع وReleaseمخطّط يبيّن المبدأ: CoCreateInstance وQueryInterface يعيدان مؤشّراً نُفِّذ عليه AddRef سلفاً، فيستدعي المستلم Release عند انتهاء الاستخدام، ويُدمَّر الكائن عندما يصل عدّاد المراجع إلى صفر.AddRef صراحةCoCreateInstance أو QueryInterfaceيعود مؤشّر نُفِّذ عليه AddRefالمستلم يستخدمهالمستلم يستدعي Releaseيُدمَّر عند وصول العدّاد إلى صفرالاحتفاظ بالمؤشّر نفسه في موضع ثانٍ

الشكل 2: المبدأ أنّ من استلم المؤشّر يستدعي Release، ولا يُستدعى AddRef صراحة إلا عند زيادة مواضع الاحتفاظ.

استخدام العقد نفسه من C# يبدو كالتالي. GUID نفسه يعني العقد نفسه، لذلك لا بأس إن كان الطرف الآخر تنفيذاً بـ C++.

using System;
using System.Runtime.InteropServices;

// اكتب GUID نفسه الذي في جانب C++. هذا إعلان «العقد نفسه»
[ComImport]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
    int Add(int a, int b);
}

// جانب الاستدعاء
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService")
         ?? throw new InvalidOperationException("خادم COM غير مسجَّل.");
object server = Activator.CreateInstance(t)!;
try
{
    var calc = (ICalcService)server;   // هذا التحويل يعادل QueryInterface
    int sum = calc.Add(1, 2);
    Console.WriteLine(sum);            // 3
}
finally
{
    Marshal.ReleaseComObject(server);  // يعادل Release
}

سبب كون قيمة Add المعادة int في جانب C# هو أنّ التشغيل البيني لـ COM في .NET يجري تحويلاً ثابتاً: «آخر وسيط [out, retval] يصير قيمة معادة، وHRESULT الفاشل يُحوَّل إلى استثناء». كذلك يختفي AddRef/Release عن شيفرة المستدعي، لكنّهما لم يزولا؛ الغلاف الرقيق الذي يوفّره .NET (RCW) يستدعيهما نيابة عنك. العقد نفسه يُستخدم بأسلوب طبيعي لكلّ لغة — هذا هو الوجه العملي لـ «العقد الثنائي».

تقابل أسلوب C# مع COMمخطّط يبيّن التقابل: في C# يعادل التحويل إلى الواجهة QueryInterface، ويعادل Marshal.ReleaseComObject دالة Release، ويُحوَّل HRESULT الفاشل إلى استثناء، ويستدعي RCW دالتي AddRef وRelease نيابة عنك.شيفرة C#التحويل إلى نوعReleaseComObjectHRESULT فاشليعادل QueryInterfaceيعادل Releaseيُحوَّل إلى استثناءRCW ينوب في عدّ المراجع

الشكل 3: حتى مع العقد نفسه، يُستبدل أسلوب C# بما يناسب اللغة، ويتولّى RCW وطبقة التشغيل البيني التحويل.

نقاط قوّة COM الأربع

1. التوافق الثنائي

يمكن إعادة استخدام مكوّن بُني مرّة واحدة بغضّ النظر عن لغة البرمجة أو زمن التشغيل. استدعاء مكوّن COM مكتوب بـ C++ من C# أو Python أمر شائع.

2. فصل الواجهة

لأنّ التنفيذ يُخفى بالكامل ويُنشر العقد فقط، يمكنك تغيير التنفيذ الداخلي بحرّية دون أثر على المستدعي.

3. تعايش الإصدارات

الأساس لإضافة وظائف مع الإبقاء على التوافق الخلفي هو إضافة واجهة جديدة. تقدّم الوظيفة الجديدة دون تغيير الواجهة القديمة.

عند جمع مستدعٍ قديم أو جديد مع مكوّن قديم أو جديد، تعمل ثلاث تركيبات من الأربع كما هي، والرابعة لا تفعل أكثر من إعادة جواب «لا أحمل هذا العقد».

QueryInterface(IID_ICalcService)S_OKQueryInterface(IID_ICalcService)S_OK ── لا ينكسر بعد التحديثQueryInterface(IID_ICalcServiceEx)S_OK ── تتاح الوظيفة الجديدةQueryInterface(IID_ICalcServiceEx)E_NOINTERFACE ── المتابعة بالوظيفة القديمةمستدعٍ قديملا يعرف سوى ICalcServiceمستدعٍ جديديسأل عن ICalcServiceExمكوّن بالإصدار القديمينفّذ ICalcService فقطمكوّن بالإصدار الجديدينفّذ الاثنين

الشكل 4: إضافة IID جديد دون تغيير الواجهة القائمة يبقي كلّ تركيب للقديم والجديد يعمل. الخطّ المتقطّع هو الجواب السليم «لا أحمل هذا العقد».

4. إعادة الاستخدام عبر حدود العملية

لمكان مكوّن COM نوعان. In-proc (خادم DLL) الذي يُحمَّل في العملية نفسها مع المستدعي كـ DLL، وOut-of-proc (خادم EXE، LocalServer) الذي يُشغَّل كـ EXE في عملية أخرى. مظهر شيفرة الاستدعاء لا يتغيّر في الحالتين.

مكانان لوضع المكوّنمخطّط يبيّن أنّ شيفرة الاستدعاء بالمظهر نفسه يمكن أن تصل إمّا إلى In-proc الذي يُحمَّل كـ DLL في عملية المستدعي، أو إلى Out-of-proc الذي يُشغَّل كـ EXE في عملية أخرى.شيفرة المستدعي (المظهر نفسه)In-proc (خادم DLL)Out-of-proc (خادم EXE)يُحمَّل كـ DLL في العملية نفسهايُشغَّل كـ EXE في عملية أخرى

الشكل 5: المكان نوعان، In-proc وOut-of-proc، لكنّ مظهر شيفرة الاستدعاء لا يتغيّر.

  In-proc (خادم DLL) Out-of-proc (خادم EXE)
مكان التنفيذ العملية نفسها مع المستدعي عملية أخرى
حقيقة الاستدعاء استدعاء مباشر عبر مؤشّر دالة إعادة تعبئة الوسائط (marshalling) وتمريرها عبر تواصل بين العمليات
السرعة سريع أبطأ بمقدار التواصل بين العمليات
إذا سقط الطرف الآخر يسقط المستدعي معه يبقى المستدعي حيّاً (يعود الاستدعاء كفشل)
عدد البتّات (32/64bit) لا يُحمَّل إن لم يتطابق يجوز أن يختلف

باستخدام Out-of-proc COM (خادم EXE) يمكنك استدعاء وظائف عملية أخرى بأمان. الصفّ الأخير «يجوز أن يختلف 32bit/64bit» ينفع في الميدان، وتركيبة استدعاء DLL بـ 64bit من تطبيق 32bit مشروحة في «دراسة حالة لجسر COM يستدعي DLL بـ 64bit من تطبيق 32bit».

غير أنّ الوجود في عملية أخرى يعني أيضاً أنّ الطرف الآخر قد يختفي في أيّ وقت. إذا تعطّلت عملية الخادم أو انتهت، يعود إلى المستدعي فشل كهذا. هذه أخطاء خاصة بـ Out-of-proc تعني «الطرف الآخر لم يعد موجوداً»، لا «انكسر شيء».

رمز الخطأ المعنى
RPC_E_DISCONNECTED الكائن الذي حاولت استدعاءه انفصل عن العميل (كائن الطرف الآخر لم يعد موجوداً)
RPC_S_SERVER_UNAVAILABLE تعذّر الوصول إلى خادم الاستدعاء (العملية)

ما كان يمكنك تجاهله في In-proc («إن سقط سقطت معه») يدخل في تصميم Out-of-proc كـ معالجة استعادة بإعادة التشغيل أو إعادة الاتّصال. الأدقّ أن تراه عملاً يزيد مقابل السلامة.

التدفّق عندما تختفي عملية الطرف الآخرمخطّط يبيّن أنّه في Out-of-proc إذا اختفت عملية الخادم بتعطّل أو إنهاء يعود الاستدعاء كفشل ويبقى المستدعي حيّاً، لذلك يلزم إدخال معالجة استعادة بإعادة التشغيل أو إعادة الاتّصال في التصميم.تعطّل عملية الخادم أو إنهاؤهايعود الاستدعاء كفشلالمستدعي يبقى حيّاًإلى معالجة الاستعادة بإعادة التشغيل أو إعادة الاتّصالليس انكساراً بل غياب الطرف الآخر

الشكل 6: في Out-of-proc لا تسقط مع الطرف الآخر إذا اختفى، وفي المقابل تدخل معالجة الاستعادة في التصميم.

تقابل العناصر الثلاثة ونقاط القوّة الأربع

كما ذكرنا في البداية، «العناصر الثلاثة» أجزاء، و«نقاط القوّة الأربع» نتيجتها. صفّ أيّ جزء يدعم أيّ قوّة فيوضّح تقسيم الأدوار الذي بدا متداخلاً.

نقطة القوّة العنصر الذي يعمل أساساً
1. التوافق الثنائي التصميم المتمحور حول الواجهة + IUnknown (ترتيب الاستدعاء يُحسم على المستوى الثنائي)
2. فصل الواجهة التصميم المتمحور حول الواجهة (نشر العقد فقط)
3. تعايش الإصدارات GUID + QueryInterface (يمكن السؤال عن عقد آخر وقت التشغيل)
4. إعادة الاستخدام عبر حدود العملية التصميم المتمحور حول الواجهة (يمكن فصل مكان التنفيذ عن العقد أيضاً)

COM ما زال في الخدمة

كثيراً ما يُظنّ «تقنية قديمة»، لكنّ COM آلية ما زالت تُستخدم في صميم Windows.

أين يُستخدم COM

  • امتدادات Explorer (قائمة النقر بالزر الأيمن، عرض المعاينة)
  • أتمتة Office (التحكّم الخارجي بـ Excel وWord)
  • التشغيل البيني مع .NET (COM Interop)
  • الأنظمة القائمة التي تضمّ ActiveX
  • عدد كبير من واجهات Windows API مثل DirectX وWindows Shell API

حتى إن ظننت أنّه «لا يعنيني»، ما دمت تطوّر لـ Windows سيظهر COM في مكان ما.

خلاصة

مركز تصميم COM هو «الاستقلال عن اللغة والعملية والتنفيذ». تصميم واجهة محايد لغوياً، وتعريف فريد وإدارة إصدارات عبر GUID، وعدّ مراجع عبر IUnknown، وآلية تعامل شفّاف مع التواصل بين العمليات.

مركز تصميم COMمخطّط يبيّن أنّ أربع آليات تسند مركز التصميم، وهو الاستقلال عن اللغة والعملية والتنفيذ: تصميم واجهة محايد لغوياً، وتعريف فريد وإدارة إصدارات عبر GUID، وعدّ مراجع عبر IUnknown، وتواصل شفّاف بين العمليات.تصميم محايد لغوياًالاستقلال عن اللغة والعملية والتنفيذتعريف فريد عبر GUIDعدّ المراجع في IUnknownتواصل شفّاف بين العمليات

الشكل 7: تجتمع أربع آليات لتسند مركز COM: «الاستقلال عن اللغة والعملية والتنفيذ».

«جميل» حكم ذاتي، لكنّ مستنده ملموس. إذا صففنا المشكلة التي حاول COM حلّها وطريقة حلّها، نحصل على التالي.

قيد كان قائماً آنذاك (وما زال) جواب COM
لا يملك C++ عقداً ثنائياً قياسياً (ABI)، فيتعذّر إعادة الاستخدام لمجرد اختلاف المترجم. لا تتوافق زخرفة الأسماء ولا تخطيط الكائن جعل العقد «ترتيب جدول الدوال الافتراضية» فقط. لأنّه اختُصر إلى هذه النقطة، لم تعد اللغة ولا المترجم مقيّدين
استبدال مكتبة يفرض إعادة بناء كلّ من يستخدمها ما دام العقد (الواجهة) لم يتغيّر، لا حاجة لإعادة البناء. يمكن الاستبدال كثنائي
تريد إضافة وظيفة دون كسر المستدعين القائمين تُضاف الواجهة دون تغييرها، ويُسأل QueryInterface وقت التشغيل «هل تحملها؟»
تصادم الأسماء (أشياء مختلفة بالاسم نفسه تتعايش) التعريف الفريد بـ GUID. ألغى الحاجة إلى ضبط الأسماء أصلاً
استدعاء وظيفة في عملية أخرى أو جهاز آخر يغيّر أسلوب كتابة الاستدعاء تماماً إدخال Proxy/Stub يحافظ على شكل شيفرة المستدعي

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

وهذه الطريقة في الحلّ ما زالت قائمة في تطوير المكوّنات المعاصر كما هي.

COM المقابل المعاصر
تثبيت العقد أوّلاً بـ IDL، وتوليد شيفرة الطرفين منه توليد العميل/الخادم من مخطّط OpenAPI أو Protocol Buffers
إضافة واجهة جديدة دون تغيير الواجهة القائمة في Protocol Buffers إضافة حقول دون إعادة استخدام أرقامها، أو تقسيم إصدارات API
اللغة غير مقيّدة (عقد ثنائي) اللغة غير مقيّدة (عقد رسائل عبر الشبكة)
Proxy/Stub يخفي حدود العملية عميل RPC stub يخفي حدود الشبكة

ما يختلف هو نوع الحدود (حدود عملية على الجهاز نفسه، أم شبكة) وتعبير العقد (ثنائي، أم نصّ/مخطّط) فقط. إذا فهمت COM، يستقرّ في تصميم واجهات الخدمات المصغّرة «لماذا يُثبَّت العقد أوّلاً» و«لماذا لا يجوز حذف حقل قائم» كضرورة، لا كموضة.

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

ما هو COM؟
COM (Component Object Model) هو «عقد ثنائي» تتواصل به المكوّنات فيما بينها على Windows. وهو آلية تتواصل عبر عقد صارم اسمه الواجهة، متجاوزة اختلافات اللغات والمترجمات. في أسسه فكرة تصميم تقول: «لا تبرمج مقابل التنفيذ، بل مقابل العقد».
ما هو IUnknown؟
الواجهة الأساسية التي ترثها كلّ واجهات COM. تقدّم ثلاث وظائف: QueryInterface للسؤال عمّا إذا كان الكائن يحمل واجهة أخرى، وAddRef لزيادة عدّاد المراجع، وRelease لإنقاص العدّاد وتدمير الكائن لنفسه عندما يصل إلى صفر. إدارة عمر كائن COM تقوم على عدّ المراجع هذا.
هل ما زال COM مستخدماً اليوم؟
نعم. COM آلية ما زالت تُستخدم في صميم Windows. تظهر في امتدادات Explorer (قائمة النقر بالزر الأيمن والمعاينة)، وأتمتة Office لـ Excel وWord، وCOM Interop مع .NET، والأنظمة القائمة التي تضمّ ActiveX، وكثير من واجهات Windows API مثل DirectX وWindows Shell API. ما دمت تطوّر لـ Windows، سيظهر COM في مكان ما.
ما نقاط قوّة COM؟
أربع نقاط رئيسة. التوافق الثنائي الذي يتيح إعادة استخدام مكوّن بُني مرّة واحدة بغضّ النظر عن اللغة أو زمن التشغيل، وفصل الواجهة الذي يخفي التنفيذ وينشر العقد فقط، وتعايش الإصدارات بإضافة واجهة جديدة مع الإبقاء على التوافق الخلفي، والاستدعاء الآمن لوظائف عملية أخرى عبر Out-of-proc COM (خادم EXE).

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

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

العودة إلى المدونة