[英]C pass void pointer using shared memory
我需要將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)。
除共享內存外還有其他備用內存嗎?
謝謝。
這可能是因為指針仍然是虛擬的; 它指向共享的內存,但不能保證共享同一內存的兩個進程將它映射到同一個虛擬地址。 物理地址當然是相同的(畢竟它是相同的實際內存)但是進程從不處理物理地址。
您可以嘗試使用mmap()
(在Linux中)進行共享來請求特定地址。 您還可以通過在兩個進程中打印共享內存塊的地址來驗證虛擬地址理論。
此外, 不要在C中轉換malloc()
的返回值,並且在您要使用共享內存時不要分配內存。 那部分沒有任何意義。
如果要從另一個進程調用進程內的函數,則不是IPC。
IPC是在多個線程/進程之間共享數據 。
考慮將共享函數添加到DLL /共享對象中以跨進程共享代碼。 如果沒有,那么你可以添加RPC到您的可執行文件的支持,顯示在這里 。
函數指針是指代功能代碼當前加載到物理存儲器中的物理存儲器位置的虛擬地址。 每當在進程中引用函數指針(虛擬地址)時,內核負責執行到物理地址的映射。 這是成功的,因為映射存在於當前進程的頁表中。
但是,當發生上下文切換並且另一個進程正在運行時,包含該特定進程的映射的頁表將被加載並且當前處於活動狀態。 這些將不包含從前一個進程的函數指針的映射。 因此,嘗試使用來自另一個進程的函數指針將失敗。
如果這樣做,那么擁有多個流程就沒有優勢。 所有可能運行的代碼都必須同時加載到物理內存中。 此外,整個系統實際上將是一個單一的過程。
實際上,每當上下文切換發生並且正在執行不同的進程時,早期進程的代碼/數據段甚至可以從物理內存中換出。 因此,即使維護函數指針並將其傳遞給新進程也是無用的,因為即使在內存中加載較新的進程並開始執行之后,它也無法保證功能代碼將保存在內存中。
這是非法的:
void *p = (void *) malloc(sizeof(void));
void
是不完整的類型, sizeof(void)
無效。 出於與無法聲明void變量相同的原因,您無法執行此操作:
void i; /* WRONG */
取消引用p
時會發生什么是未定義的。 如果你只想要指針值,你不需要在read.c
上調用malloc
- 這就是共享內存的整個概念 - 如果它是共享的,你為什么要在閱讀器程序上分配空間?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.