首先,要分享您的
int *a
字段指向的内容,您需要复制与此相关的所有内存。因此,您需要一个共享内存,其大小至少为
size_t shm_size = sizeof(struct ex) + get_the_length_of_your_ex();
。
从现在开始,由于您提到了shmget和shmat,我假设您运行的是Linux系统。
第一步是
创建共享内存段
。如果您可以确定上限大小,则最好确定
int *a
内容的大小。这样就不必一遍又一遍地创建/删除共享内存段。但如果这样做,则需要额外的开销来说明实际数据的长度。对于此目的,我将假定一个简单的
size_t
就足够了。
然后,在您创建段之后,必须正确设置数据以使其保持所需内容。请注意,虽然内存段的物理地址始终相同,但调用
shmat
时,您将获得
虚拟 指针,这些指针仅在调用
shmat
的进程中可用。下面的示例代码应该能给您一些技巧。
#include <sys/types.h>
#include <sys/ipc.h>
#define A_MAX_SIZE (size_t)4096
struct ex {
int *a;
int b;
int c;
}
int shm_create(void)
{
key_t k = ftok("/a/path/of/yours");
int shm_id = 0;
if (0 > (shm_id = shmget(
k, sizeof(struct ex) + A_MAX_SIZE + sizeof(size_t), IPC_CREAT|IPC_EXCL|0666))) {
}
return shm_id;
}
int shm_fill(int shmid, struct ex *p_ex)
{
void *p = shmat(shmid, NULL, 0);
void *tmp = p;
size_t data_len = get_my_ex_struct_data_len(p_ex);
if ((void*)(-1) == p) {
return -1;
}
memcpy(tmp, p_ex, sizeof(struct ex));
tmp += sizeof(struct ex);
memcpy(tmp, &data_len, sizeof(size_t);
tmp += 4;
memcpy(tmp, p_ex->a, data_len);
shmdt(p);
return 0;
}
int shm_get_ex(int shmid, struct ex *p_dst)
{
void *p = shmat(shmid, NULL, SHM_RDONLY);
void *tmp;
size_t data_len = 0;
if ((void*)(-1) == p) {
return -1;
}
data_len = *(size_t*)(p + sizeof(struct ex))
if (NULL == (tmp = malloc(data_len))) {
shmdt(p);
return -1;
}
memcpy(p_dst, p, sizeof(struct ex));
memcpy(tmp, (p + sizeof(struct ex) + sizeof(size_t)), data_len);
p_dst->a = tmp;
return 0;
}
void shm_detach_struct(struct ex *p_ex)
{
shmdt(p_ex->a - sizeof(struct ex) - sizeof(size_t));
p_ex->a = NULL;
}
请原谅我的懒惰,为了优化空间,在共享内存中完全不使用“struct ex”中的“int *a”指针的值时,最好不要复制它的值。但是我省略了额外的代码来处理此问题(以及一些指针检查,例如“p_ex”参数的完整性)。
但是,完成后,您必须找到一种方法在进程之间分享shm ID。这可以使用套接字、管道等方式完成...或者使用相同输入的ftok
。