我需要将void处理程序传递给另一个应用程序,要复制方案,我使用共享内存创建了一个小程序,并尝试将void指针传递给另一个应用程序并打印该值,我可以在另一个应用程序中获取void指针地址应用程序,但是当我尝试取消引用指针第二个应用程序崩溃时。
以下是示例应用程序wire.c。
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
int main() {
key_t key=1235;
int shm_id;
void *shm;
void *vPtr;
shm_id = shmget(key,10,IPC_CREAT | 0666);
shm = shmat(shm_id,NULL,NULL);
sprintf(shm,"%d",&vPtr);
printf("Address is %p, Value is %d \n", (void *)&vPtr, * (int *)vPtr);
return;
}
这是read.c
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
key_t key=1235;
int shm_id;
void *shm;
void *p = (void *)malloc(sizeof(void));
shm_id = shmget(key,10,NULL);
shm = shmat(shm_id,NULL,NULL);
if(shm == NULL)
{
printf("error");
}
sscanf(shm,"%d",&p);
printf("Address is %p %d\n",(void *)p);
return 0;
}
当我尝试取消引用时它会崩溃。我需要在第二个应用程序中传递void指针地址和值。
我不想在应用程序之间共享价值,我知道它使用共享内存。
默认情况下,void * ptr会有一些garbadge值(例如add = 0xbfff7f,value = 23456),请告诉我,如何将void指针地址传递给另一个应用程序以及使用该地址的第二个应用程序我可以打印在第一次申请中找到的值(即23456)。
除共享内存外还有其他备用内存吗?
感谢。
答案 0 :(得分:1)
这可能是因为指针仍然是虚拟的;它指向共享的内存,但不能保证共享同一内存的两个进程将它映射到同一个虚拟地址。 物理地址当然是相同的(毕竟它是相同的实际内存),但进程从不处理物理地址。
您可以尝试使用mmap()
(在Linux中)进行共享来请求特定地址。您还可以通过在两个进程中打印共享内存块的地址来验证虚拟地址理论。
此外,don't cast the return value of malloc()
in C并且在您打算使用共享内存时不分配内存。那部分没有任何意义。
答案 1 :(得分:1)
如果要从另一个进程调用进程内的函数,则不是IPC IPC在多个线程/进程之间共享数据。
考虑将共享函数添加到DLL /共享对象中以跨进程共享代码。如果没有,那么您可以向您的可执行文件添加RPC支持,如 here 所示。
函数指针是一个虚拟地址,指的是功能代码当前加载到物理内存中的物理内存位置。每当在进程中引用函数指针(虚拟地址)时,内核负责执行到物理地址的映射。这是成功的,因为映射存在于当前进程的页表中。
但是,当发生上下文切换并且另一个进程正在运行时,包含该特定进程的映射的页表将被加载并且当前处于活动状态。这些将不包含从前一个进程的函数指针的映射。因此,尝试使用来自另一个进程的函数指针将失败。
如果这样做,那么拥有多个流程就没有优势。所有可能运行的代码都必须同时加载到物理内存中。此外,整个系统实际上将是一个单一的过程。
实际上,每当上下文切换发生并且正在执行不同的进程时,先前进程的代码/数据段甚至可以从物理内存中换出。因此,即使维护一个函数指针并将其传递给新进程也是无用的,因为即使在内存中加载了较新的进程并开始执行之后,它也无法保证函数代码将保存在内存中。
答案 2 :(得分:0)
这是非法的:
void *p = (void *) malloc(sizeof(void));
void
是不完整的类型,sizeof(void)
无效。出于与无法声明void变量相同的原因,您无法执行此操作:
void i; /* WRONG */
取消引用p
时未完成的内容会发生什么。如果您只想要指针值,则无需在malloc
上调用read.c
- 这是共享内存的整个概念 - 如果共享,为什么要分配读者计划的空间?