0

How to properly register all callback from a DLL and make the callback call? I have been blocked on this issue for a while and finally i came up with a workaround... currently, this is how i register my callback from a DLL...

i had to use dumpbin /export MyDLL.dll to get the addresses, the register like this...

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

My question is, i want to do it the "proper" way, assuming if there is one. Why do i have to resort to dumbin and then putting in a weird GetProcAddress in the form _ObjectDllCallback@4 which is very cryptic.

Is there a proper way to get my register callback function the right way?

void __stdcall MyCallbackFunc(const char* str)
{
    printf("%s\n", str);
}
Tim
  • 133
  • 1
  • 13
  • Possible duplicate of [How do I stop name-mangling of my DLL's exported function?](https://stackoverflow.com/questions/1467144/how-do-i-stop-name-mangling-of-my-dlls-exported-function) – Thomas Lang Mar 29 '19 at 05:08

2 Answers2

0

What you are seeing is "C++ name mangling" where the C++ compiler generates unique names for linkage. To avoid the name mangling you can declare your function inside of an extern C clause, for example along those lines:

#define APICALL  __declspec(dllexport) 

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

Then you can use

LPCALLBACKFUNC fnObjectDllCallback = (LPCALLBACKFUNC) GetProcAddress(hDll, "ObjectDllCallback");
J.R.
  • 1,880
  • 8
  • 16
  • No thats not it. i already have that declared in extern C like the way you did it, but it still doesnt work. – Tim Mar 29 '19 at 05:15
  • @Tim That surprises me. Could you post your full declaration including the 'extern C' part and any 'declspec'? The function is implemented in a 'cpp' file, correct? – J.R. Mar 29 '19 at 05:36
  • Please see my answer post, i had to post like that to put in code. – Tim Apr 01 '19 at 09:33
0

Here is the header file

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

and here is the CPP file

// 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);
        }
    }
}
Tim
  • 133
  • 1
  • 13
  • Hi Time, you'll need to take the `extern C` statement and `typedef`s out of the `XInterface` namespace. In the `cpp` file, you don't need the functions decorated with `OBJECTDLL_API` and `__stdcall` file but add it to all exported functions in the header. Also, you don't need to have `OBJECTDLL_API` on the class object if you intend to just export C-style functions. --- Note that you can edit your original question to add code etc; no need to post as answer (maybe delete this answer and add your code to original question). – J.R. Apr 01 '19 at 19:46