简体   繁体   English

C使用共享内存传递void指针

[英]C pass void pointer using shared memory

I need to pass void handler to another application, To replicate the scenario I have created one small program using shared memory and try to pass the void pointer to another application and print the value, I can get the void pointer address in another application, but when I try to dereference the pointer second application crash. 我需要将void处理程序传递给另一个应用程序,要复制方案我使用共享内存创建了一个小程序并尝试将void指针传递给另一个应用程序并打印该值,我可以在另一个应用程序中获取void指针地址,但是当我尝试取消引用指针第二个应用程序崩溃时。

Here are the sample application wire.c . 以下是示例应用程序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;
}

Here is read.c 这是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;
}

When I try to dereference p it crash. 当我试图取消引用它崩溃。 I need to pass the void pointer address and value in second application. 我需要在第二个应用程序中传递void指针地址和值。

I don't want to share value between application, It works using shared memory,I know. 我不想在应用程序之间共享价值,它使用共享内存,我知道。

By default void *ptr will have some garbadge value (for ex. add= 0xbfff7f, value=23456), Can you please tell me, how can i pass void pointer address to another application and from the second application using that address i can print the value which was found in first application (ie 23456). 默认情况下,void * ptr会有一些garbadge值(例如add = 0xbfff7f,value = 23456),你能告诉我,我怎样才能将void指针地址传递给另一个应用程序,并从第二个应用程序使用该地址我可以打印第一次申请中发现的价值(即23456)。

Apart from the shared memory is there any other alternate available? 除共享内存外还有其他备用内存吗?

Thanks. 谢谢。

This is probably because the pointer is still virtual; 这可能是因为指针仍然是虚拟的; it's pointing at memory that is shared but there is no guarantee that two processes sharing the same memory maps it to the same virtual address. 它指向共享的内存,但不能保证共享同一内存的两个进程将它映射到同一个虚拟地址。 The physical addresses are of course the same (it's the same actual memory, after all) but processes never deal with physical addresses. 物理地址当然是相同的(毕竟它是相同的实际内存)但是进程从不处理物理地址。

You can try to request a specific address by using mmap() (in Linux) to do the sharing. 您可以尝试使用mmap() (在Linux中)进行共享来请求特定地址。 You can also verify the virtual address theory by simply printing the addresses of the shared memory block in both processes. 您还可以通过在两个进程中打印共享内存块的地址来验证虚拟地址理论。

Also, don't cast the return value of malloc() in C and don't allocate memory when you're going to be using the shared memory. 此外, 不要在C中转换malloc()的返回值,并且在您要使用共享内存时不要分配内存。 That part just makes no sense. 那部分没有任何意义。

If you want to call a function within a process from another process, it is NOT IPC. 如果要从另一个进程调用进程内的函数,则不是IPC。
IPC is sharing of data between multiple threads/processes. IPC是在多个线程/进程之间共享数据

Consider adding the shared function into a DLL/shared-object to share the code across processes. 考虑将共享函数添加到DLL /共享对象中以跨进程共享代码。 If not, then you could add RPC support to your executables as shown here . 如果没有,那么你可以添加RPC到您的可执行文件的支持,显示在这里


Why passing function pointers between 2 process does NOT work? 为什么在2个进程之间传递函数指针不起作用?

A function pointer is a virtual address referring to the physical memory location where the function code is currently loaded into physical memory. 函数指针是指代功能代码当前加载到物理存储器中的物理存储器位置的虚拟地址。 Whenever a function pointer(virtual address) is referred to in the process, the kernel is responsible for performing the mapping to physical address. 每当在进程中引用函数指针(虚拟地址)时,内核负责执行到物理地址的映射。 This is successful as the mapping is present in the page-tables for the current process. 这是成功的,因为映射存在于当前进程的页表中。

However when a context-switch occurs and another process is running, the page-tables containing the mappings of that particular process are loaded and currently active. 但是,当发生上下文切换并且另一个进程正在运行时,包含该特定进程的映射的页表将被加载并且当前处于活动状态。 these will NOT contain the mapping of the function pointer form the previous process. 这些将不包含从前一个进程的函数指针的映射。 Hence attempting to use the function pointer from another process will fail. 因此,尝试使用来自另一个进程的函数指针将失败。

Why the page-tables do NOT contain the mapping of function in another process? 为什么页表不包含另一个进程中的函数映射?

If this was done then there would be no advantages with having multiple processes. 如果这样做,那么拥有多个流程就没有优势。 All the code that could ever be run would have to be loaded into physical memory simultaneously. 所有可能运行的代码都必须同时加载到物理内存中。 Also the entire system would then effectively be a single process. 此外,整个系统实际上将是一个单一的过程。

Practically speaking whenever a context-switch happens and a different process is executing, the code/data segments of the earlier process can even be swapped out of physical memory. 实际上,每当上下文切换发生并且正在执行不同的进程时,早期进程的代码/数据段甚至可以从物理内存中换出。 Hence even maintaining a function pointer and passing it to the new process is useless as it cannot guarantee that the function code will be held in memory even after newer process is loaded in memory and starts executing. 因此,即使维护函数指针并将其传递给新进程也是无用的,因为即使在内存中加载较新的进程并开始执行之后,它也无法保证功能代码将保存在内存中。

This is illegal: 这是非法的:

void *p = (void *) malloc(sizeof(void));

void is an incomplete type, sizeof(void) is invalid. void是不完整的类型, sizeof(void)无效。 You can't do this for the same reason that you can't declare a void variable: 出于与无法声明void变量相同的原因,您无法执行此操作:

void i; /* WRONG */

What happens when you dereference p is undefined. 取消引用p时会发生什么是未定义的。 If you just want the pointer value, you don't need to call malloc on read.c - that's the whole concept of shared memory - if it's shared, why would you allocate space on the reader program? 如果你只想要指针值,你不需要在read.c上调用malloc - 这就是共享内存的整个概念 - 如果它是共享的,你为什么要在阅读器程序上分配空间?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM