C3374: لا يمكن أن تأخذ عنوان 'وظيفة' ما لم يخلق المثال مندوب

StackOverflow https://stackoverflow.com/questions/822582

  •  03-07-2019
  •  | 
  •  

سؤال

وأواجه صعوبة في استخدام وظيفة تسجيل مكتبة الأطراف الثالثة لتسجيل الاستدعاء. وأنا أكتب في C ++ CLI، والوصول إلى مكتبة مكتوب في C أو C ++.

وماذا يعني خطأ المترجم أعلاه؟

وهذه هي وظيفة تسجيل كما هو محدد من قبل البائع:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);

وهذا هو رد على النحو المحدد من قبل البائع:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);

وبلدي رد ظيفة:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

ودعوتي (الذي فشل):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);
هل كانت مفيدة؟

المحلول

وإذا كان لي أن الرهان تخمين، كنت في محاولة لأخذ عنوان دالة تدار وتمريرها على أنها مؤشر الدالة الأصلية. وهذا لا تعمل على الإطلاق. إما إرسال الجسر الأصلي (أصعب وربما لا ميزة)، أو (وهذا هو النهج الأسهل)، إنشاء مندوب واستخدام <لأ href = "http://msdn.microsoft.com/en-us/library/system .runtime.interopservices.marshal.getfunctionpointerfordelegate.aspx "يختلط =" noreferrer "> Marshal.GetFunctionPointerForDelegate . لا ننسى أن مندوب لديه للبقاء على قيد الحياة لمدة التي يتوقع التعليمات البرمجية الأصلية للاتصال مرة أخرى، لذلك كنت على الأرجح بحاجة لتخزينه في مكان ما.

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

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

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);

وبعد ذلك، ستحتاج إلى إنشاء واحد:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

وكما ذكر سابقا، يجب تخزين هذا في صفك بوصفه عضوا في أجل التأكد من أنها لا تختفي. وأخيرا، تحتاج إلى الحصول على مؤشر الدالة ويمر عليه:

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);

وأعتقد أن يغطي كل شيء. كل ما تحتاجه هو استخدام نظام مساحة الاسم. ويجب أن يكون على ما يرام.

نصائح أخرى

وظائفها رد الاتصال هي عضو - مؤشر للأعضاء ومؤشرات إلى وظائف أشياء مختلفة

.

وحتى في حل Promit ل:

CallbackFuncDelegate(CallbackFunc)
يجب

وCallbackFunc لا يكون عضو فئة

ويمكنك كتابة ببساطة

public ref class Device 
{
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

وثم استخدم

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