我有一个文件API.c,其中有某些功能,但没有主要功能。
在其中一个函数中,我调用shmat()并返回:
#include<stdio.h>
#include<stdlib.h>
#include<sys/shm.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/stat.h>
#include<signal.h>
int array1[100]; // TO STORE THE SHMIDs
int array2[100]; // TO STORE THE RSHMIDs
char * array3[100]; //TO STORE THE SHMAT ADDRESSES
struct msgbuf
{
long type;
int key;
int rshmid;
int size;
void * addr;
int cmd;
int pid;
int shmid;
};
struct msgbuf my,rec;
int queue_id;
int rshmget(int key,int size)
{
queue_id = msgget(1234, IPC_CREAT | 0666);
printf("1\n");
my.type =1;
my.key=key;
my.size=size;
my.pid=getpid();
//SENDING REQUEST OF CLIENT TO SERVER
if (msgsnd (queue_id, &(my), sizeof (my), 0) == -1)
{
perror("msgsnd");
}
//SERVER CREATES SHARED MEMORY AND WRITES THE REPLY BACK
while(1)
{
if (msgrcv (queue_id, &(rec), sizeof (rec), getpid(), IPC_NOWAIT) != -1)
{
printf("GOT MSG\n");
break;
}
sleep(1);
}
//ARRAY 1 STORES THE ACTUAL SHMID OF SHARED MEMORY
//ARRAY 2 STORES RSHMID , WHICH IS THE ID RETURNED TO CLIENT
array1[key%100] = rec.shmid;
array2[key%100] = rec.rshmid;
return rec.rshmid;
}
void * rshmat(int rshmid, void* addr)
{
my.type =2;
my.rshmid = rshmid;
my.pid=getpid();
int i;
// IDENTIFYING THE SHMID CORRESPONDING TO THE RSHMIDS
for(i=0;i<100;i++)
{
if(array2[i]==rshmid)
break;
}
//ARRAY 3 STORES THE ADDRESSES CORRESPONDING TO EACH SHMAT
array3[i] = shmat(array1[i],NULL,0);
//INFORMING THE SERVER ABOUT THE ATTACHING
if (msgsnd (queue_id, &(my), sizeof (my), 0) == -1)
{
perror("msgsnd");
}
return array3[i];
}
在main.c文件中,我这样做:
int main()
{
queue_id = msgget(1234, IPC_CREAT | 0666);
int id1 = rshmget(521,200);
char * addr1 = (char *)rshmat(id1,NULL);
strcpy(addr1,"FIRST MESSAGE 123456");
}
尝试执行strcpy语句时,会发生分段错误。
但是如果我将API函数和main保存在同一个文件中,strcpy就会成功执行。
根据我的理解,shmat()将在堆中返回一个指针,因此它应该可以从main访问。
当代码在同一个文件中时它可以工作的事实可能表明我没有正确链接文件,但API.c文件中的其他函数能够正确返回。
这就是我编译的方式:
gcc -c API.c
gcc -c main.c
gcc main.o API.o -o client
我正在使用LINUX操作系统。
答案 0 :(得分:0)
在这两个文件中,为您使用的每个函数添加原型,并在其前面添加标识符为extern
的其他文件。
e.g。在文件main.c
中添加extern void * rshmat(int shm_id);