注册和调用 DLL 回调的正确方法是什么
What's the proper way to register and call DLL callback
如何正确注册来自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);
}
}
}
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 通过JNI传递数据数组的最快方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在C++中包含原型文件的正确方法是什么?
- 在 OpenCV C++ 中估计基本矩阵之前对相应点进行归一化的正确方法是什么?
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- 从长整整转换为uint64_t的推荐方法是什么?
- 将此布尔值传递给此函数的最有效方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?