我的代码如下:
extern "C" __declspec(dllexport) myInterface(int id, void** pFunction)
{
...
}
我需要使void ** pFunction参数指向一个函数,以便调用者可以通过pFunction指针使用此函数。这个函数通过DLL调用,我不想这样做,但由于很多原因我别无选择。我知道COM是为此而制作的,但是我不能使用它,原因归结为管理层。
此时我不知道该怎么做,我试图做的每件事都给我带来了问题。有谁知道我怎么能这样做?如果不清楚,我可以发布更多内容。
感谢。
答案 0 :(得分:3)
如果您正在查看'myInterface'的实现,那么您可能需要:
switch (id)
{
case FUNC_1:
*pFunction = (void *)first_function;
break;
...
}
如果您尝试调用该函数并传入指向函数的指针,则:
void *vp = (void *)the_function_to_pass;
myInterface(1, &vp);
如果你还有其他想法,你需要指明一下。
(注意,严格来说,C不保证函数指针可以分配给对象指针,反之亦然。但是,POSIX确实为你做了这个保证。我相信类似的注释适用于C ++。)
答案 1 :(得分:1)
这不是可以在标准C或C ++中完成的事情。无法保证函数指针可以适合void指针(C ++成员函数指针通常不能)。换句话说,如果您无法更改功能签名,则无法在标准C或C ++中执行所需操作,并且无法保证您可以执行此操作。
因此,任何解决方案都是特定于平台的解决方案。您没有直接指定问题或标记的平台,但我的猜测是其他东西的Visual C ++。
请具体指定您的平台,以及有关您想要传递的函数指针的任何有用信息。
答案 2 :(得分:1)
这很棘手,但我很幸运,代码是这样的:
*reinterpret_cast<void**>( &(PVOID&)( DetourFunc ) ) = (PVOID) 0x00FFFF00;
根据我的理解,这个概念是你引用一个引用,重新解释引用,然后取消引用它。有点混乱,但我可以验证它是否有效。你也可以在右侧放置一个地址(&amp; func),它就可以了。使用以下形式调用DetourFunc:
(DetourFunc)(param, param)
将调用原始地址或函数。
编辑:这样可行,但似乎是对语言的滥用。但它确实有效,并且在此处的其他几个问题中也有所建议。
答案 3 :(得分:1)
正如Jonathan Leffler和David Thornley所提到的,你无法保证函数指针可以转换为void*
并返回。一个可移植的解决方法是将函数指针打包到struct
并传递指针。
(请注意void**
itself might have its own issues。您也可以避免这种情况。)
例如:
typedef int (*SomeFuncType)(int);
struct FuncWrapper
{
SomeFuncType func;
void* output;
};
...
FuncWrapper funcWrapper;
funcWrapper.func = ...;
myInterface(id, &funcWrapper);
然后myInterface可以实现为:
void myInterface(int id, FuncWrapper* funcWrapper)
{
funcWrapper->func(...);
funcWrapper->output = ...;
}
答案 4 :(得分:0)
我要感谢大家的帮助。以下是我至少部分工作的方式。基本上包装理念是有效的。
struct myProj { virtual HRESULT __stdcall myMethod(unsigned short *&amp; myname); };
HRESULT __stdcall myMethod(unsigned short *&amp; myname) { myname = L“myname”;
返回(1); }
struct myProj xProject;
要打电话:
extern“C”HRESULT __declspec(dllexport)fInterface(UINT id,LPVOID * pObj) { 开关(ID) { 案例FVI_ID: * pObj =&amp; xProject; 打破; } }
这确实调用了正确的函数,但它仍然存在问题。第三方DLL使用CStrings,我怀疑他们提出了我的其他问题以及它们包含的一些跟踪功能。
我相信我的真正解决方案是我无法伪造com,我们需要意识到DLL不能在我们的项目中使用。
谢谢大家。