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

What's the proper way to register and call DLL callback

本文关键字:方法 是什么 回调 调用 DLL 注册      更新时间:2023-10-16

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

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

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

我的问题是,我想以"适当"的方式做,假设如果有的话。为什么我必须求助于哑巴,然后以_ObjectDllCallback@4的形式输入一个奇怪的 GetProcAddress,这非常神秘。

有没有正确的方法可以以正确的方式获取我的寄存器回调函数?

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

您看到的是"C++名称重整",其中C++编译器为链接生成唯一的名称。为了避免名称重整,您可以在 extern C 子句中声明函数,例如:

#define APICALL  __declspec(dllexport) 
extern "C" 
{
   APICALL void _stdcall ObjectDllCallback(LPCALLBACKFUNC callbackFunction);
};

然后你可以使用

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

这是头文件

#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("%sn", __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("%sn", __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);
        }
    }
}