עזרה ב ++C

sharon669

New member
עזרה ב ++C

שלום , אני תקוע עם בעייה אני אשמח אם תוכלו לעזור לי , כתבתי DLL שמבצע פעולה מסויימת , וברגע שיש לו מידע מוכן הוא מודיע לאפליקציה שהטעינה אותו באמצעות פונקציית CallBack ה DLL עובד יפה בתכנות ++C קונבנציונאלי , אבל ב MFC זה לא עובד בתכנות Win32 רגיל אני מודיע ל DLL איזה פונקצייה להפעיל באפליקציה פשוט על ידי שליחת כתובת הפונקצייה כ LONG נניח שהפונקציה שמקבלת את המידע באפליקצייה נקראת : ()ReciveData אז אני מפעיל פונקצייה של ה DLL ושולח את הכתובת של הפונקצייה כך :
SetCallBackFuncAddr(&ReciveData)​
אבל בMFC זה לא עובד !! אודה לכל מי שיזרוק לי כיוון ! תודה שרון
 

DNile

New member
אני פשוט שונא..

שונא... כשאנשים באים ואומרים "זה לא עובד", ולא מסבירים איך זה לא עובד! במקרה, רק במקרה, אני חושב שהצלחתי להבין את הבעיה שלך, אבל זה עם הרבה מאוד ניחושים. הפונקציה שאתה מנסה להעביר את הכתובת שלה, היא Member function של איזה class, נכון? אז אתה לא יכול. רק פונקציות גלובליות או סטטיות יכולות להיות מועברות ככה.
 

galh

New member
אתה תמיד יכול לענות תשובה בסגנון...

כמו, "אה, תלחץ F5 ואז זה יעבוד..."
לחבר'ה בפורום של לינוקס יש מקבילה ל- "לא עובד". משהו דומה ל- "התקנתי לינוקס ועכשיו אני רק רואה מסך שחור שכתוב בו login".
 

sharon669

New member
אני פשוט שונא ....

אנשים שנותנים תשובות לא שלמות ...
אתה צודק לא נתתי מספיק פרטים .. בתצורה הנוכחית אני עובד עם פונקציה גלובלית סטטית אם יש לך הצעה איך לבצע את הקריאה החוזרת הזאת , אז פשוט תתן דרך או דוגמא .... למה לא ניתן לשלוח כתובת של Member function ?????? שרון .
 

sharon669

New member
הנה הקוד :

הקוד נכתב בתכנות ++C קונבנציונאלי : לקוח מתוך קוד גורו (קישור)
Library Source: DLL_Callback.h #ifndef _DLL_CALLBACK_ #define _DLL_CALLBACK_ // All declarations which are needed resides in "windows.h" #include <windows.h> // Placeholder for function-export macros #define LIBRARY_EXPORT __declspec(dllexport) __cdecl // Function Declarations for Static Export extern "C" { long LIBRARY_EXPORT GetDBData(void); long LIBRARY_EXPORT SetCallbackProcAddr(long); } // Function Declaration for Callback function // of the Calling App typedef void (* TDataReadNotify)(long); #endif DLL_Callback.cpp // Comment out the line below, if you want STDCALL // for the VB-Example. #define CDECL_CALLING_CONVENTION #ifdef CDECL_CALLING_CONVENTION #include "DLL_Callback.h" #else #include "DLL_Callback_StdCall.h" #endif // Vars for Imported Functions TDataReadNotify DataReadNotify; HANDLE hThread; DWORD pThreadId; DWORD DoTheWork(LPVOID lpParameter) { long lDBData; // Doing stuff that takes 5 sec., i.e. reading DB Data. // ... Sleep(5000); lDBData = 123; // ... // Notify the caller app via CB-function. if (DataReadNotify != NULL) DataReadNotify(lDBData); return 0; }; long LIBRARY_EXPORT GetDBData(void) { long lProcAdr; // Get ProcAddress for Thread-Func and create/run the thread. lProcAdr = (long)(&DoTheWork); hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lProcAdr, NULL, 0, &pThreadId); // Return to caller app. return 0; }; long LIBRARY_EXPORT SetCallbackProcAddr(long lProcAddress) { long Result = 0; // Set the Proc-Address for the notify-func of // the caller app. DataReadNotify = (TDataReadNotify)lProcAddress; if (DataReadNotify != NULL) Result = 1; return Result; }; C++ Sample Source: Callback_Sample.h #ifndef _CALLBACK_SAMPLE_ #define _CALLBACK_SAMPLE_ // All declarations which are needed resides // in "windows.h" #include <windows.h> // Placeholder for function-import macros #define LIBRARY_IMPORT __declspec(dllimport) __cdecl // Function Declarations for Static // Import (aka "Implicied Linking") // This requires the Output-LIB of the DLL_Callback Library. extern "C" { int LIBRARY_IMPORT GetDBData(void); int LIBRARY_IMPORT SetCallbackProcAddr(long); } #endif Callback_Sample.cpp #include "Callback_Sample.h" int iWait = 1; char sDBData[11]; char sMessage[64]; void DataReadNotify(long lDBData) { _ltoa(lDBData, sDBData, 10); strcpy(sMessage, "DBData from DLL is: "); strcat(sMessage, sDBData); ::MessageBox(0, sMessage, "Sample App", MB_OK + MB_ICONINFORMATION); // Set Wait to 0, so that WinMain can go further. iWait = 0; }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { long lProcAdr; // Get Address-Pointer of the CB-function lProcAdr = (long)(&DataReadNotify); // Send Address-Pointer Information to the DLL SetCallbackProcAddr(lProcAdr); // Call the function of the DLL, which reads DB-Info // or something else. GetDBData(); // Do other work while the DLL reads the DBData // ... // I.e.: Show a splash-screen, write values to an // INI-File or whatever // ... // if the DLL-function is still busy, loop until // the DLL notifies via the CALLBACK-function "DataReadNotify()". while (iWait) {}; return 0; };​
 

vinney

Well-known member
נראה בסדר... זה הקוד שלא עובד?

תוכל להסביר לי רק למה אתה דוחס מצביעים לתוך long? זה לא ממש בריא, אולי זה מקור הבעיה שלך. עקרונית מצביע יכול להיות גם 8 בתים, וlong בחלונאחס הוא 4 בתים, לא מסתדר (קוד גורו כתבו ככה? לא יפה) בד"כ אחרי שעשית typedef לפונקציה משתמשים בtype שנוצר להעביר את הפונקציה כפרמטר, המרות LONG די חסרות טעם. לגבי הcreatethread - יש לך את LPTHREAD_START_ROUTINE בתור type להעברה, גם אין צורך בlong.
 

DadleFish

New member
עוד לא קנית לך את הזכות להתלונן

על התשובות של DNILE. בכל אופן, הסיבה לכך שזה לא עובד ב-member function היא ש-member function חייבת להיקרא כחלק מאובייקט מסוים, ולא יכולה להיקרא גלובלית. אתה יכול להשתמש בפונקציה סטטית בתוך ה-class עצמו, מה שהופך אותה לפונקציה גלובלית למעשה, או שתעבור דרך פונקציה גלובלית שתקרא לפונקציה הספציפית באינסטנס הרצוי. בשביל זה תצטרך לפחות פרמטר נוסף שיישלח אל הפונקציה הגלובלית, ודרכו תיקרא ה-method. הנה דוגמה קטנה:
class MyClass { public: void DoSomething(); }; void GlobalDoSomething(void *p) { MyClass *pInstance = static_cast<MyClass *>(p); pInstance->DoSomething(); }​
 
למעלה