如何让 void** 指向函数?
我的代码如下所示:
extern "C" __declspec(dllexport) myInterface(int id, void** pFunction)
{
...
}
我需要使 void** pFunction 参数指向一个函数,以便调用者可以通过 pFunction 指针使用该函数。这个函数是通过 DLL 调用的,我不想这样做,但由于很多原因我别无选择。我知道COM是为此而设计的,但我不能使用它,原因归结于管理。
此时我不知道该怎么做,我尝试做的一切都给我带来了演员问题。有谁知道我该怎么做?如果不清楚的话我可以发布更多内容。
谢谢。
I have code that looks like this:
extern "C" __declspec(dllexport) myInterface(int id, void** pFunction)
{
...
}
I need to make the void** pFunction argument point to a function so that the caller can use this function via the pFunction pointer. This function gets called through a DLL, I don't want to do it this way but for a lot of reasons I have no choice. I know that COM is made for this but I can not use it, the reasons come down to management.
At this point I have no idea how to do this, everything I have tried to do gives me cast problems. Do anyone have any idea how I can do this? I can post more if this is unclear.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您正在查看“myInterface”的实现,那么您可能会想要:
如果您尝试调用该函数并传入函数指针,那么:
如果您还有其他想法,则需要指定什么。
(严格来说,C 并不保证函数指针可以分配给对象指针,反之亦然。但是,POSIX 确实为您提供了这一保证。我相信类似的评论也适用于 C++。)
If you are looking at the implementation of 'myInterface', then you might be wanting:
If you are trying to call the function and pass in a pointer to function, then:
If you have something else in mind, you need to specify what.
(Note that strictly, C does not guarantee that function pointers can be assigned to object pointers and vice versa. However, POSIX does make that guarantee for you. I believe similar comments apply to C++.)
正如 Jonathan Leffler 和 David Thornley 提到的,不能保证函数指针可以转换为
void*
并返回。一个可移植的解决方法是将函数指针打包到一个结构体中,并传递一个指向该结构体的指针。(请注意,
void**
本身可能有自己的问题. 你也可以避免这种情况。)例如:
然后 myInterface 可以实现为:
As Jonathan Leffler and David Thornley mentioned, you aren't guaranteed that a function pointer can be converted to
void*
and back. A portable workaround would be to package the function pointer into astruct
and to pass a pointer to that.(Be aware that
void**
itself might have its own issues. You can avoid this too.)For example:
and then myInterface could be implemented as:
这不是标准 C 或 C++ 可以完成的事情。不能保证函数指针可以适合 void 指针(C++ 成员函数指针通常不能)。换句话说,如果您无法更改函数签名,则无法在标准 C 或 C++ 中执行您想要的操作,并且根本无法保证您可以执行此操作。
因此,任何解决方案都将是特定于平台的解决方案。您没有直接指定有问题或标记的平台,但我的猜测是 Visual C++ 或其他平台。
请具体指定您的平台,以及有关您要传递的函数指针的任何有用信息。
This is not something that can be done in standard C or C++. There is no guarantee that a function pointer can fit into a void pointer (C++ member function pointers typically can't). In other words, if you can't change the function signature, you can't do what you want in standard C or C++, and there's no guarantee you can do it at all.
Therefore, any solution would be a platform-specific one. You don't specify a platform directly in question or tag, but my guess would be Visual C++ from other things.
Please specify your platform specifically, and anything useful about the function pointer you want to pass.
这很棘手,但我对这样的代码很幸运:
据我了解,这个概念是您引用一个引用,重新解释该引用,然后取消引用它。有点令人困惑,但我可以验证它是否有效。您还可以在右侧放置一个地址(&func),它就会起作用。调用DetourFunc,使用形式:
将调用原始地址或函数。
编辑:这可行,但似乎是对该语言的严重滥用。不过,它确实有效,并且已在此处的其他几个问题中得到推荐。
It's tricksy, but I've had good luck with code like so:
The concept, as I understand it, is you're referencing a reference, reinterpreting the reference, then dereferencing it. Bit confusing, but I can verify it works. You can also put an address on the right side (&func) and it'll work. Calling DetourFunc, using the form:
will call the original address or function.
Edit: This works, but it seems like a pretty heavy abuse of the language. It does work, though, and has been recommended in a few other questions here.
我要感谢大家的帮助。这是我让它至少部分工作的方法。基本上,包装器的想法是有效的。
结构myProj
{
虚拟 HRESULT __stdcall myMethod(unsigned Short* & myname);
};
HRESULT __stdcall myMethod(无符号短* & myname)
{
我的名字 = L"我的名字";
返回(1);
}
结构 myProj xProject;
调用它:
extern "C" HRESULT __declspec(dllexport) fInterface(UINT id, LPVOID * pObj)
{
开关(ID)
{
案例 FVI_ID:
*pObj = &xProject;
休息;
}
这
确实调用了正确的函数,但仍然存在问题。第三方 DLL 使用 CStrings,我怀疑它们给我带来了其他问题以及它们包含的一些跟踪函数。
我相信我真正的解决方案是我不能伪造 com,我们需要意识到 DLL 不能在我们的项目中使用。
谢谢大家。
I want to thank everyone for help. Here is how I get it to work at least in part. Basically the wrapper idea works.
struct myProj
{
virtual HRESULT __stdcall myMethod(unsigned short* & myname);
};
HRESULT __stdcall myMethod(unsigned short* & myname)
{
myname = L"myname";
return(1);
}
struct myProj xProject;
To call it:
extern "C" HRESULT __declspec(dllexport) fInterface(UINT id, LPVOID * pObj)
{
switch(id)
{
case FVI_ID:
*pObj = &xProject;
break;
}
}
This does call the correct function, but it still has it's problems. The third party DLL uses CStrings and I suspect they are giving my other problems as well as some trace functions they contain.
I believe my real solution is I can't fake out the com, that we need to realize the DLL's can not be used in our project.
Thanks everyone.