Как правильно регистрировать и вызывать колбэк DLL? - PullRequest
0 голосов
/ 29 марта 2019

Как правильно зарегистрировать все обратные вызовы из DLL и сделать обратный вызов? Я был заблокирован по этому вопросу некоторое время, и, наконец, я нашел обходной путь ... в настоящее время, это, как я регистрирую свой обратный вызов из DLL ...

Мне пришлось использовать dumpbin / export MyDLL.dll, чтобы получить адреса, регистр вот так ...

LPCALLBACKFUNC ObjectDllCallback = (LPCALLBACKFUNC) GetProcAddress(hDll, "_ObjectDllCallback@4");
ObjectDllCallback(MyCallbackFunc);

Мой вопрос: я хочу сделать это "правильным" способом, предполагая, если таковой имеется. Почему я должен прибегнуть к dumbin, а затем вставить странный GetProcAddress в форме _ObjectDllCallback @ 4 , что очень загадочно.

Есть ли правильный способ правильно настроить функцию обратного вызова моего регистра?

void __stdcall MyCallbackFunc(const char* str)
{
    printf("%s\n", str);
}

Ответы [ 2 ]

0 голосов
/ 01 апреля 2019

Вот заголовочный файл

#ifdef OBJECTDLL_EXPORTS
#define OBJECTDLL_API __declspec(dllexport)
#else
#define OBJECTDLL_API __declspec(dllimport)
#endif

#define MAX_BUFF_STR_SIZE 256

namespace XInterface
{
    // exported global var
    extern OBJECTDLL_API int nObjectDll;

    // Object Base class
    class CObjectDllBase {
    public:

        // TODO: add your pure virtual methods here.
        virtual int InvokeMethod() const = 0;
        virtual int InvokeMethod(const char*, char*, int) const = 0;

        // object callback interface
        typedef void (__stdcall* CallbackMethod)(const char*, void*);
        virtual void InvokeCallback(CallbackMethod, void*) = 0;
    };

    // This class is exported from the ObjectDll.dll
    class OBJECTDLL_API CObjectDll : public CObjectDllBase {
    public:

        CObjectDll();

        // TODO: add your methods here.
        int InvokeMethod() const;
        int InvokeMethod(const char* str, char* res, int size) const;

        // demonstrate object callback
        void InvokeCallback(CallbackMethod funcname, void* context);

    private:

        CallbackMethod m_callback;
    };

    // exported functions to be accessed externally
    extern "C"
    {
        // ordinary functions
        OBJECTDLL_API int   ObjectDllMethod();
        OBJECTDLL_API int   ObjectDllFunction(const char* str, char* res, int size);

        // demonstrate callback
        typedef void  (__stdcall* CallbackFunc)(const char*);
        OBJECTDLL_API void  __stdcall ObjectDllCallback(CallbackFunc funcname);

        // virtual class object./
        OBJECTDLL_API void* ObjectDllCreate();
        OBJECTDLL_API void  ObjectDllFree(void* pObj);
        OBJECTDLL_API void  ObjectDllInvokeMethod(void* pObj);

        // wrapper for class callback
        typedef void (__stdcall* CallbackMethod)(const char*, void*);
        OBJECTDLL_API void  __stdcall ObjectDllInvokeCallback(void* pObj, CallbackMethod funcname, void* context);
    };

    // exported typedefs to be accessed externally [one defined for each exported declaration]
    typedef int   (*LPFUNC)(const char*, char*, int);
    typedef void  (*LPCALLBACKFUNC)(CallbackFunc);
    typedef void  (*LPCALLBACKMETHOD)(CallbackMethod);

    typedef void* (*LPOBJECTCREATE)(void);
    typedef void  (*LPOBJECTFREE)(void*);
};

и вот файл CPP

// ObjectDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "stdio.h"
#include "ObjectDll.h"

namespace XInterface
{
    // This is an example of an exported variable
    OBJECTDLL_API int nObjectDll=0;

    // This is an example of an exported function.
    OBJECTDLL_API int ObjectDllMethod()
    {
        printf("%s\n", __FUNCTION__);
        return 0;
    }

    OBJECTDLL_API int ObjectDllFunction(const char* str, char* res, int size)
    {
        memset(res, 0, size);
        _snprintf(res, size, "%s%s", str, __FUNCTION__);
        return 0;
    }

    OBJECTDLL_API void __stdcall ObjectDllCallback( CallbackFunc funcname )
    {
        CallbackFunc callbackfunc = funcname;

        if (callbackfunc)
        {
            // ... some work here... then lets call our function
            callbackfunc(__FUNCTION__);
        }
    }

    OBJECTDLL_API void* ObjectDllCreate()
    {
        return new CObjectDll();
    }

    OBJECTDLL_API void ObjectDllFree( void* pObj )
    {
        CObjectDll* pObjDll = static_cast<CObjectDll*>(pObj);
        if (pObjDll)
        {
            delete pObjDll;
            pObjDll = NULL;
        }
    }

    OBJECTDLL_API void ObjectDllInvokeMethod( void* pObj )
    {
        CObjectDll* pObjDll = static_cast<CObjectDll*>(pObj);
        if (pObjDll)
        {
            pObjDll->InvokeMethod();
        }
    }

    /*
    OBJECTDLL_API void __stdcall ObjectDllInvokeCallback( void* pObj, CallbackMethod funcname, void* context )
    {
        CObjectDll* pObjDll = static_cast<CObjectDll*>(pObj);
        if (pObjDll)
        {
            pObjDll->InvokeCallback(funcname, context);
        }
    }
    */

    // This is the constructor of a class that has been exported.
    // see ObjectDll.h for the class definition
    CObjectDll::CObjectDll()
    {}

    int CObjectDll::InvokeMethod() const
    {
        printf("%s\n", __FUNCTION__);
        return 0;
    }

    int CObjectDll::InvokeMethod(const char* str, char* res, int size) const
    {
        memset(res, 0, size);
        _snprintf(res, size, "%s%s", str, __FUNCTION__);
        return 0;
    }

    void CObjectDll::InvokeCallback( CallbackMethod funcname = NULL, void* context = NULL)
    {
        m_callback = funcname;

        if (m_callback)
        {
            // ... some work here... then lets call our function
            m_callback(__FUNCTION__, context);
        }
    }
}
0 голосов
/ 29 марта 2019

То, что вы видите, это "искажение имен C ++", где компилятор C ++ генерирует уникальные имена для связи.Чтобы избежать искажения имени, вы можете объявить свою функцию внутри предложения extern C, например, в следующих строках:

#define APICALL  __declspec(dllexport) 

extern "C" 
{
   APICALL void _stdcall ObjectDllCallback(LPCALLBACKFUNC callbackFunction);
};

Тогда вы можете использовать

LPCALLBACKFUNC fnObjectDllCallback = (LPCALLBACKFUNC) GetProcAddress(hDll, "ObjectDllCallback");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...