是安全的周围通过函数指针和比较他们就像正常的对象的指针? [英] is it safe to pass function pointers around and compare them just like normal object's pointers?

查看:112
本文介绍了是安全的周围通过函数指针和比较他们就像正常的对象的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一回事,我有几个功能,

Here is the thing, I have several functions,

void foo() {}
void bar() {}

和我想通过左右这些功能就像普通对象的指针,

And I want to pass these functions around just like ordinary objects' pointers,

int main()
{
    void (*fptr1)() = foo;
    void (*fptr2)() = fptr1;
    void (*fptr3)() = bar;

    if (fptr1 == foo)
        printf("foo function\n");
    if (fptr2 == foo)
        printf("foo function\n");
    if (fptr3 == foo)
        printf("foo function\n")
}

我可以使用这些函数指针这种方式?我写了一个程序来测试它,好像ok了。此外,我认为,不喜欢它可能位于,函数在<$ C $普通对象C>文本段(右),所以当我指的是,它给我在哪个函数<$ C $的物理地址C>富在于文本段?

Can I use these function pointers this way? And I wrote a program to test it, seems like ok. Furthermore, I think, not like ordinary objects which may lie in stack or heap, functions reside in text segment (right?), so when I refer to foo, does it give me the physical address at which function foo lies in the text segment?

跟进

如果我确实有DLL工作,考虑一下:第一,功能PTR FPTR 分配功能,

If I indeed work with DLL, consider this: first, a function ptr fptr is assigned a function,

ReturnType (*fptr)(ArgType) = beautiful_func;

下面两种情况,

1)如果beautiful_func不是DLL,那么它是安全的使用这个 FPTR

1) if beautiful_func is not in DLL, then it is safe to use this fptr.

2)如果是在DLL,再后来,我认为这将是不安全的使用 FPTR ,因为现在可能指的是完全不同的功能,这是不 FPTR 诞生了,是吧?

2) if it is in DLL, then later, I think it would be unsafe to use fptr, because it now may refer to a totally different function which is not fptr was born for, right?

推荐答案

您可以检查两个函数指针是相等的只是通过简单的==他们,因为他们只是正常的指针。这是显而易见的。

You can check if two function pointers are equal just by simply == them, as they are just normal pointers. That's obvious.

但是,当你说比较,请检查你真的在你的心中:

However, when you are say "compare", check what you really have in your mind:


  • 您有兴趣检测你被赋予不同的东西

  • 或你有兴趣检测你被赋予不同的功能?

比较指针(不仅仅是函数指针它适用于所有的人!)是一个有点冒险:你不检查的内容(逻辑标识),但只是位置(物理标识)。大多数时候,它确实是相同的,但有时,要小心,你偶然发现的副本。

comparing pointers (not only function pointers! it applies to all of them) is a bit risky: you are not checking the contents (logical identity), but just the location ("physical" identity). Most of the time it really is the same, but sometimes, beware, you stumble upon copies.

很明显,如果你创建的数字1,2,3,4的数组,然后分配另一个阵列和复制的内容有,那么你会得到两个不同的指针,对不对?但数组可能是同样的话,这取决于你需要什么。

It is obvious that if you create an array with numbers 1,2,3,4 and then allocate another array and copy the contents there, then you get two different pointers, right? But the array may be SAME for you, depending on what you need it for.

通过函数指针的问题是一样的,甚至更多:您是不知道什么编译器/连接器已与您的code完成。它可能opitmized一些东西,它可能已经合并了一些不导出功能结合在一起,如果注意到他们平等的,它可能复制或内联等。

With function pointers the problem is just the same, and even more: you don't actually know what the compiler/linker has done with your code. It might have opitmized few things, it might have merged some not-exported functions together if it noticed them equal, it might have copied or inlined others.

特别是可能与更大的独立的子项目时发生。想象一下,你写了一个排序函数,然后包括它的子项目A和子项目B,编译/构建的一切,然后链接和运行。你将与​​一个排序函数或两个结束?难以回答的问题,直到你真正检查并正确地定制链接选项。

Especially that may happen when working with bigger separate "subprojects". Imagine you wrote a sorting function, then include it with subproject A, and subproject B, compile/build everything, then link and run. Will you end with one sort functions or two? Hard question until you actually check and tailor the linkage options properly.

这是比数组更复杂一点。有了数组,你有不同的指针,如果数组是不同的。这里,相同的功能可以具有许多不同的地址。它的可能与C ++模板时,但也取决于链接器如何做他的工作。呵呵,很好的例子,尤其引人注目:DLL文件。基于类似code三的DLL,他们几乎都guaranteeded拥有一切的三个副本它们静态链接到。

This is a bit more complex than with arrays. With arrays, you got different pointer if the array was different. Here, the same function may have many different addresses. It might be especially noticeable when working with templates in C++, but that again depends on how well the linker did his job.. Oh, great example: DLLs. With three DLLs based on similar code, they almost have guaranteeded to have three copies of everything they were statically linked to.

和talkig当即将DLL的......你知道,他们可以加载/卸载额外的code到你的记忆,对不对?这意味着,当你加载DLL,一些地址XYZ出现的功能。然后您卸载它,它就会消失。但是,当你现在加载不同的dll?当然操作系统被允许重新使用的空间中,并允许它一个新加载DLL映射到相同的区域previous之一。大部分的时间你不会注意到它,因为新加载的DLL会映射到不同的地区,但可能发生

And when talkig about DLLs... You know that they can load/unload additional code into your memory, right? This means that when you load a DLL, at some address XYZ a function appears. Then you unload it, and it goes away. But when you now load different DLL? Of course the OS is allowed to reuse the space, and it is allowed to map a newly loaded DLL into the same area as previous one. Most of the time you will not notice it, as newly loaded DLL will be mapped into different region, but it may happen.

这意味着,虽然你可以比较指针,你得到的唯一答案是:是的指针相同或不

This means that while you can compare the pointers, the only answer you get is: are the pointers same or not?


  • 如果他们不一样的,那么你的根本不知道;不同的函数指针的意味着该功能是不同的。它可能是这样,这将是这样的情况下的99%,但并不必须是不同

  • if they not same, then you SIMPLY DON'T KNOW; different function pointer does not mean that the function is different. It may be so, it will be so in 99% of cases, but does not have to be different

如果他们是相同的:


  • 如果你不加载/卸载各种动态库大量的时候,你可能会认为,没有什么变化,你可以肯定得到了相同的函数/对象/数组作为前

  • if you are NOT loading/unloading the various dynamic libraries large number of times, you might assume that nothing changes and you may be sure got the same function/object/array as before

如果您正在卸载的动态模块工作时,你最好不要假设所有,除非你的绝对确定没有指针的来根据将在未来被卸载的DLL。请注意,一些图书馆使用插件式功能的动态库。小心从它们的指示,并留意插件加载/卸载通知。你的函数可能更改时,动态库被卸载。

if you are working with unloadable dynamic modules, you'd better not assume that at all, unless you are absolutely sure that none of the pointers comes from a DLL that will be unloaded in future. Note that it some libraries use dynamic libraries for "plugin-like" functionality. Be careful with pointers from them, and watch for plugin load/unload notifications. Your function may change when a dynamic library is unloaded.

编辑跟帖:

除非你(或你使用库)曾经的卸载的DLL,然后将鼠标指针到功能 - 即的目标-A-DLL是使用安全。

Unless you (or some library you use) ever unload the DLL, then your pointer-to-function-that-targets-a-DLL is safe to use.

一旦加载DLL时,可以改变地址的意义,这个DLL采取了恶的就是卸载的动态模块

Once the DLL is loaded, the only evil thing that can change the meaning of address that this DLL has taken is unloading the dynamic module.

如果您确信:


  • (1)无论是你的指针到函数不针对从动态模块功能(静态联点code只)

  • (2)或它的目标是一个动态模块,但动态模块的卸载从未(OK:直到程序退出或崩溃)

  • (3)或它的目标是一个动态的模块,你precisely知道是哪一个,那动态模块有时运行期间卸载,但您的code得到一些'有关事实事先通知

  • (1) either your pointer-to-function does not target a function from dynamic module (points to statically-linked code only)
  • (2) or it targets a dynamic module, but that dynamic module is never unloaded (ok: until program quits or crashes)
  • (3) or it targets a dynamic module, and you precisely know which one, and that dynamic module is sometimes unloaded during the runtime, but your code gets some 'prior notification' about that fact

那么你的函数指针是安全的存储和使用,并比较,只要你添加一些安全措施:

then your pointer to function is safe to store and use and compare, provided that you add some safety measures:


  • 为(1),没有必要的安全措施:该功能将不会被替换

  • 对于(2),没有必要的安全措施:功能不会得到,直到程序退出

  • 为(3),安全措施需要:你一定要听这些通知,一旦你收到通知的DLL被卸载,您必须immediatelly忘记所有的指针该目标DLL。你还是安全的,必须记住任何其他。你仍然安全地重新想起它时,它被再次加载。

  • for (1), no safety measures are needed: the functions will not get replaced
  • for (2), no safety measures are needed: the functions will not get until program quits
  • for (3), safety measures are needed: you must listen to those notifications, and once you get notified about DLL being unloaded, you must immediatelly forget all pointers that target DLL. You are still safe to remember any other. You are still safe to re-remember it when it gets loaded again.

如果你怀疑你的指针到函数不从的目标,将在一定的时间点被卸载动态模块功能程序退出之前,和:

If you suspect that your pointer-to-function does targets a function from dynamic module that will be unloaded at some point of time before program quits, and:


  • 您实际上不知道哪个DLL是由指针指向

  • 或DLL会的卸载在任何时候,恕不另行通知

  • you don't actually know which DLL is pointed by that pointer
  • or that DLL will be unloaded at any point without any notice

那么你的指针功能的不安全可言使用。并通过在所有我的意思是任何方式都没有。不要保存它,因为它可能会瞬间蒸发立即

then your pointer to function is unsafe to use at all. And by at all I mean AT ALL in any way. Dont store it, as it may instantly evaporate immediately.

这篇关于是安全的周围通过函数指针和比较他们就像正常的对象的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆