كيفية استدعاء DLL بنظام 64 بت من تطبيق 32 بت - دراسة حالة عملية لجسر COM

· آخر تحديث: · · COM, تطوير Windows, 32 بت, 64 بت

سجل التعديلات (النسخة الأولى، نُشرت في 25 Jan، 2026)
النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621305)

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

小村 豪 (2026). كيفية استدعاء DLL بنظام 64 بت من تطبيق 32 بت - دراسة حالة عملية لجسر COM. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621305 https://comcomponent.com/ar/blog/2026/01/25/002-com-case-study-32bit-to-64bit/

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

كيفية استدعاء DLL بنظام 64 بت من تطبيق 32 بت - دراسة حالة عملية لجسر COM

تُعدّ الحاجة إلى استدعاء DLL بنظام 64 بت من تطبيق 32 بت متطلَّباً شائعاً جدّاً في بيئة Windows. وعندما ترغب في الإبقاء على أصل قائم بنظام 32 بت مع استخدام الوظائف الجديدة المتاحة في الجانب 64 بت فقط، فإنّ جسر COM يكون في الغالب الإجابة الأكثر عملية.

المحتويات

  1. الوضع المفترض
  2. الحلّ
  3. مسار المعالجة (مخطّط التتابع)
  4. نموذج الكود (تصوّري)
  5. نموذج الكود الكامل
  6. مراجع

1. الوضع المفترض

الحالة هنا بسيطة: ترغب في الإبقاء على تطبيق قائم بنظام 32 بت، ولكنّك في الوقت نفسه بحاجة إلى استخدام منطق يقع داخل DLL بنظام 64 بت.
المشكلة هي أنّ عملية 32 بت لا يمكنها تحميل DLL بنظام 64 بت. وهذا قيد قائم على مستوى نظام التشغيل.

تبدو الظروف الاعتيادية على النحو التالي:

  • التطبيق القائم بنظام 32 بت أكبر من أن يُرحَّل فوراً
  • يحتوي DLL بنظام 64 بت على وظائف جديدة، أو أنّ إحدى مكتباته التابعة متاحة فقط بصيغة 64 بت
  • تريد استدعاء هذه الوظائف من جانب 32 بت عبر واجهة مكتوبة (typed interface)

في مثل هذا الوضع، يكون استدعاء الـ DLL داخل العملية نفسها أمراً مستحيلاً.

2. الحلّ

الحلّ الأساسي هو الفصل بين العالمَين باستخدام COM خارج العملية (out-of-process)، أي خادم EXE.
يقوم خادم COM بنظام 64 بت (EXE) بتحميل DLL بنظام 64 بت، بينما يستخدم تطبيق 32 بت ذلك الخادم عبر COM.

يجري ذلك على النحو التالي:

  1. تحضير COM LocalServer بنظام 64 بت (EXE) يستدعي داخلياً DLL بنظام 64 بت
  2. مشاركة واجهة COM (IDL / TypeLib) بحيث تُنشَر الأنواع بصورة ثابتة
  3. السماح لتطبيق 32 بت باستدعاء COM عبر تلك الواجهة المكتوبة، مع تكفّل Proxy / Marshaling بمعالجة الحدود

ثمّة بعض التنبيهات المهمّة:

  • تسجيل 32 بت و 64 بت منفصل، ويتضمّن ذلك WOW6432Node
  • البِنى المخصّصة (custom structs) تتطلّب تصميم marshalling صريح
  • يضيف IPC تكلفةً إضافية، ولذا تستوجب الاستدعاءات عالية التكرار عناية إضافية

وعليه، فإنّ النهج المعتاد هو نقل عمل 64 بت إلى عملية أخرى ثم إقامة جسر إليه عبر COM.

3. مسار المعالجة (مخطّط التتابع)

يُبيّن ما يلي مسار الاستدعاء حين يستدعي تطبيق 32 بت وظائف داخل DLL بنظام 64 بت.

rgba(100,100,255,0.1) Handled automatically by COM (no manual work for the developer)64-bit DLL64-bit COM Server(EXE)COM Stub(64-bit side)RPC/IPC(inter-process transport)COM Proxy(32-bit side)32-bit client application64-bit DLL64-bit COM Server(EXE)COM Stub(64-bit side)RPC/IPC(inter-process transport)COM Proxy(32-bit side)32-bit client applicationMarshal parametersUnmarshal parametersMarshal return valueUnmarshal return valueICalcService.Add(1, 2)Serialized dataTransfer across the process boundaryAdd(1, 2)Native function callResult: 3Result: 3Serialized resultTransfer across the process boundaryResult: 3

النقاط الجوهرية:

  • يستطيع تطبيق 32 بت الاستدعاء عبر واجهة ICalcService بأسلوب آمن من حيث الأنواع (type-safe)
  • يقوم زمن تشغيل COM تلقائياً بإنشاء طبقة Proxy / Stub وإدارتها
  • بما أنّ الاستدعاءات بين العمليات تنطوي على تكلفة إضافية، فإنّ تجميع الاستدعاءات (batching) يُفضَّل عادةً على إجراء عدد كبير من الاستدعاءات الصغيرة

4. نموذج الكود (تصوّري)

ما يلي رسم تصوّري للفكرة. أمّا في مشروع حقيقي فلا تزال تحتاج إلى التسجيل وتوليد TypeLib والإعداد المحيط بذلك.

// Shared interface (equivalent to the IDL contract)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
    int Add(int a, int b);
}

// 64-bit COM LocalServer (EXE side)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
public class CalcService : ICalcService
{
    public int Add(int a, int b)
    {
        // The 64-bit DLL is called here
        return a + b;
    }
}

// 32-bit application side (client)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);

بهذه البنية يستطيع جانب 32 بت الاستمرار في استخدام الخدمة عبر واجهة برمجية مكتوبة (typed API).
يتولّى COM داخلياً إدارة عمل Proxy / Stub ويُمرّر الاستدعاء عبر IPC.

5. نموذج الكود الكامل

نشرتُ نموذجاً عملياً قابلاً للتشغيل لهذا النهج على GitHub.

Call64bitDLLFrom32bitProc - GitHub

يحتوي المستودع على:

  • Call64bitDLLFrom32bitProc/ - خادم COM LocalServer بنظام 64 بت (EXE)
  • X64DLL/ - الـ DLL بنظام 64 بت الذي يضمّ التنفيذ الفعلي
  • X86App/ - التطبيق العميل بنظام 32 بت (WinForms)
  • scripts/ - سكربتات لتسجيل خادم COM وإلغاء تسجيله

إذا قمتَ ببناء النموذج وتسجيله باتّباع تعليمات README، يمكنك التحقّق فعلياً من سلوك استدعاء DLL بنظام 64 بت من عملية 32 بت.

6. مراجع

  • بوّابة Component Object Model (COM)
    https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
  • تسجيل LocalServer32
    https://learn.microsoft.com/en-us/windows/win32/com/localserver32
  • أساسيات COM
    https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
  • COM Interop من .NET
    https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop

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

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

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

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

غو كومورا

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

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

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