注册和调用DLL回调的正确方法是什么

时间:2019-03-29 03:54:18

标签: c++ callback

如何正确注册DLL中的所有回调并进行回调调用? 我已经在这个问题上被阻止了一段时间,最后我想出了一种解决方法...目前,这就是我从DLL注册回调的方法...

我不得不使用dumpbin / export MyDLL.dll来获取地址,像这样的寄存器...

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

我的问题是,我想以“适当的”方式进行操作,假设是否存在这种情况。为什么我必须求助于dumbin,然后以 _ObjectDllCallback @ 4 的形式输入一个奇怪的GetProcAddress,这很神秘。

是否有正确的方法来获取我的注册回调函数?

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

2 个答案:

答案 0 :(得分:0)

您看到的是“ C ++名称修改”,其中C ++编译器生成用于链接的唯一名称。为了避免名称混乱,您可以在extern C子句中声明函数,例如,沿着这些行:

#define APICALL  __declspec(dllexport) 

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

然后您就可以使用

LPCALLBACKFUNC fnObjectDllCallback = (LPCALLBACKFUNC) GetProcAddress(hDll, "ObjectDllCallback");

答案 1 :(得分:0)

这是头文件

#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);
        }
    }
}