例如,如果我在主应用程序中声明一个函数,并从动态加载的库(通过Linux下的dlopen
或Windows下的LoadLibrary
)传递指向它的指针,则使用getten符号参数(分别通过dlsym
或GetProcAddress
)并尝试调用该函数,它会正常工作吗?
如果将指针从一个动态加载的库传递到另一个库,则相同吗?我认为如果指针至少相对于应用程序而不是相对于模块/库,它应该工作。
另一个例子。我在一个应用程序中声明一个函数并将指针传递给另一个完全独立的应用程序(包括C和C ++)(参数字符串或文件i / o - idk如何,只是一个想法)并尝试调用此函数,是否会工作呢?如果指针是绝对的,我可以期待它工作。也许它只是赢了工作,因为系统因为安全而完全不喜欢这样的交叉呼叫?
答案 0 :(得分:7)
首先你必须明白,在C和C ++中,指针的值不需要与实际使用的地址相关,只要指针算法与它一起工作,空指针的R值为0并且实现设法在机器指针和语言抽象指针之间进行双射映射。
在现代系统进程中,查看虚拟地址空间,每个进程都有自己的地址空间。库可以加载到任何地址,因此在进程之间传递指针完全是胡说八道 - 至少在分页内存架构上。但是在一个进程机器级别指针在加载的库之间传递没有问题;毕竟他们共享相同的地址空间。如果多种语言接触,在语言层面上它们可能不一样(尽管通常都是相同的)。但是使用相同编译器创建的编译单元将使用相同的指针语义。此外,大多数针对本机的语言实现都同意指针语义,原因很简单,必须在指针格式之间进行转换会产生巨大的性能损失。
答案 1 :(得分:7)
绝对。
它是虚拟地址的事实与此无关 - 它是一个绝对虚拟地址。无论是使用虚拟内存还是物理内存,它都会使你的程序没有区别 ...除非你在进程之间传递指针,否则你不应该关注这个问题。我非常怀疑你是谁,或者除非你手动编写低级内核代码或映射/取消映射页面(我也怀疑你是这样)。
答案 2 :(得分:5)
在不同的操作系统上,工作方式不同。在较旧的/嵌入式操作系统上,所有进程共享相同的空间 - 一个进程很容易让另一个进程混乱。
在大多数通用(即非嵌入式)现代操作系统中,每个进程都有一个单独的地址空间。所有地址都与此空间有关。如果编译/链接在一起并不重要,如果它们在同一个进程中,它们共享地址空间。
由此可见,两个不同的进程没有隐含的方式来访问每个其他空间。
答案 3 :(得分:4)
归因于MMU。它是大多数处理器中的硬件单元,用于保护应用程序。其主要目的是保护内核/操作系统免受应用程序的攻击每个应用程序或进程都有自己的内存,不能访问其他进程的内存,但必须以某种方式通过内核/操作系统。