سؤال

لقد قرأت العديد من البرامج التعليمية/المقالات حول ملفات DLL غير المُدارة في C++.ومع ذلك، طوال حياتي، يبدو أنني لا أستطيع فهم هذا المفهوم.أنا في حيرة من أمري بسبب الخلاف الواضح حول ما إذا كان يحتاج إلى ملف رأس، وكيفية تصديره، وما إذا كنت بحاجة إلى ملف .lib وماذا لديك.

لذا، لنفترض أن لدي وظيفة مثل:

public int calculateSquare(int num)
{
    return num*num;
}

بتجاهل الكود الفعلي، ما الذي أحتاجه لتحويل هذه الوظيفة البسيطة بمفردها إلى ملف DLL يمكنني الاتصال به بعد ذلك؟هل أقوم فقط بإضافة __dllexport أو أي شيء آخر إلى السطر الأول أم أحتاج إلى رأس؟أنا في حيرة من كل هذا.

هل كانت مفيدة؟

المحلول

لا أستطيع أن أؤكد هذا يكفي، مترجم C ++ لا يرى رأس الملفات، بعد الانتهاء من المعالج، هناك واحد فقط ملف مصدر كبير (وتسمى أيضا وحدة تجميع). لذلك بدقة لا تحتاج رأس لتصدير هذه الوظيفة من DLL. ما تفعله تحتاجه هو شكل من أشكال الترجمة الشرطية لتصدير وظيفة في دلل التي تقوم بتجميع ولاستيراده في رمز العميل.

وعادة ما يتم ذلك مع مجموعة من وحدات الماكرو والملفات رأس. قمت بإنشاء ماكرو يسمى MYIMPORTEXPORT ومن خلال استخدام العبارات الشرطية الكلية التي تجعل من العمل مثل __declspec (dllexport) في دلل، و__declspec (dllimport) في رمز العميل.

وفي ملف MYIMPORTEXPORT.h

#ifdef SOME_CONDITION
#define MYIMPORTEXPORT __declspec( dllexport )
#else
#define MYIMPORTEXPORT __declspec( dllimport )
#endif

وفي ملف MyHeader.h

#include <MyImportExport.h>

MYIMPORTEXPORT public int calculateSquare(int num)
{
    return num*num;
}

في الملف .cpp دلل

#define SOME_CONDITION

#include <MyHeader.h>

وفي العميل ملف .cpp كود

#include <MyHeader.h>

وبالطبع تحتاج أيضا للإشارة إلى رابط أنك بناء دلل مع في / DLL الخيار .

وعملية البناء وأيضا جعل ملف .LIB، وهذا هو ليب ثابت - دعا كعب في هذه الحالة - التي يحتاج رمز العميل لتصل إلى كما لو كانت تربط إلى ليب ثابت حقيقي. التلقائى، سيتم تحميل DLL عند تشغيل التعليمات البرمجية العميل. بالطبع يحتاج دلل التي يمكن العثور عليها من قبل نظام التشغيل من خلال آلية البحث، والذي يعني أنك لا يمكن وضع دلل فقط في أي مكان، ولكن في مكان معين. هنا أكثر على ذلك.

وأداة قوية جدا لمعرفة ما إذا كان تصدير الدالة الصحيح من DLL، وما إذا كان رمز العميل تستورد بشكل صحيح هو <وأ href = "http://support.microsoft.com/kb/177429" يختلط = " نوفولو noreferrer "> DUMPBIN . تشغيله مع / الصادرات و / الواردات على التوالي.

نصائح أخرى

والجواب QBziZ 'هو الحق بما فيه الكفاية. انظر غير المدارة في C ++

لإكمال ما يلي: في C ++، إذا كنت بحاجة إلى استخدام الرمز، يجب أن نقول للمترجم كان موجودا، وكثير من الأحيان، النموذج الأولي

.

في لغات أخرى، فإن المترجم مجرد استكشاف مكتبة من تلقاء نفسها، والعثور على الرمز، <م> وآخرون فويلا .

في C ++، يجب أن نقول للمترجم.

انظر C / C ++ رأس كجدول كتاب محتويات

وأفضل طريقة هي وضع في مكان مشترك رمز المطلوبة. "واجهة"، إذا كنت تريد. وعادة ما يتم هذا في ملف الرأس، ودعا رأس لأن هذه هي عادة ليست ملف مصدر مستقل. رأس هو فقط ملف الذين ليتم تضمينها الهدف (أي نسخ / لصق من قبل المعالج) في ملفات مصدر الحقيقية.

في الجوهر، على ما يبدو لديك ليعلن مرتين رمز (وظيفة، والطبقة، أيا كان). الذي يكاد يكون بدعة بالمقارنة مع اللغات الأخرى.

وسترى ذلك في كتاب، مع جدول ملخص، أو فهرس. في الجدول، لديك كل الفصول. في النص، لديك الفصول ومضمونها.

وأحيانا، كنت سعيدا فقط لديك قائمة الفصل.

في C ++، وهذا هو الرأس.

وماذا عن DLL؟

وهكذا، مرة أخرى إلى مشكلة DLL: إن الهدف من DLL هو تصدير الرموز التي سوف تستخدم الشفرة

.

وهكذا، بطريقة C ++، يجب أن كلا تصدير التعليمات البرمجية في تجميع (أي في ويندوز، استخدام __declspec، على سبيل المثال)، و "نشر" جدول ما يتم تصديره (أي أن رؤوس "العامة" التي تحتوي على الإعلانات المصدرة).

قائمة مرجعية لتصدير الوظائف:

  • هل اصطلاح الاتصال مناسب للمتصل؟(هذا يحدد كيفية تمرير المعلمات والنتائج، ومن المسؤول عن تنظيف المكدس).يجب عليك ذكر اصطلاح الاتصال الخاص بك بشكل صريح.
  • تحت أي اسم سيتم تصدير الرمز؟تحتاج لغة C++ عادةً إلى تزيين ("تشويه") أسماء الرموز، على سبيل المثال.للتمييز بين الأحمال الزائدة المختلفة.
  • اطلب من الرابط أن يجعل الوظيفة مرئية كتصدير DLL

على MSVC:

  • __stdcall (وهو اصطلاح استدعاء باسكال) هو اصطلاح الاتصال النموذجي للرموز المصدرة - التي يدعمها معظم العملاء على ما أعتقد.
  • يسمح لك "C" الخارجي بتصدير الرمز C-style دون تشويه الاسم
  • يستخدم __declspec(dllexport) لوضع علامة على رمز ليتم تصديره، أو ربط ملف .def منفصل حيث يتم سرد الرموز المراد تصديرها.باستخدام ملف .def، يمكنك أيضًا التصدير بالترتيب الترتيبي فقط (وليس بالاسم)، وتغيير اسم الرمز الذي يتم تصديره.

وتحتاج إلى تصدير الدالة باستخدام either__declspec( dllexport ) أو إضافة وظيفة لملف تعريف الوحدة النمطية (.DEF). ثم ترجمة ثو المشروع باعتباره DLL.

وعلى جانب العميل، لديك خياران. إما استخدام مكتبة الاستيراد (.LIB) التي يتم إنشاؤها عند تجميع DLL. ببساطة ربط مع مشروع العميل الخاص بك مع هذه المكتبة تعطيك الوصول إلى وظائف تصديرها من DLL. وكنت في حاجة الى ملف الرأس، لأن المترجم يحتاج إلى معرفة توقيع الدالة - أن تقوم بإرجاع كثافة العمليات ويأخذ عدد صحيح. وباختصار، تحتاج إلى ربط مع مكتبة الاستيراد (.LIB) وملف رأس الذي يحتوي على رأس الدالة.

وهناك طريقة أخرى لتحميل DLL حيوي باستخدام دعوة WinAPI LoadLibrary ثم GetProcAddress الحصول على مؤشر إلى وظيفة. مؤشر إلى وظيفة يجب أن يكون النوع الصحيح، بحيث يمكن أن تعطي مترجم انها المعلمات الصحيحة، ويستخدم اصطلاح استدعاء الصحيحة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top