C 函数指针执行错误

C 函数指针执行错误,c,function,pointers,structure,void-pointers,C,Function,Pointers,Structure,Void Pointers,这是我定义的结构 typedef enum { TCP = 1, UDP }protocol; typedef enum { DLL_Operation = 1, MT_Operation, Fork_Operation, IPC_Operation }msgc; struct f { int seqNo; protocol p; msgc m; protocol q; int PayLoadSize;

这是我定义的结构

typedef enum
{
    TCP = 1,
    UDP
}protocol;

typedef enum
{
    DLL_Operation = 1,
    MT_Operation,
    Fork_Operation,
    IPC_Operation
}msgc;

struct f
{
    int seqNo;
    protocol p;
    msgc m;
    protocol q;
    int PayLoadSize;
    void (*payload_ptr)();
};
现在,我在函数指针中获取函数的地址,并将其从服务器发送到客户端

这是我的服务器端代码

struct f f2;

if(f2.m == 1)
{                                                                           
    f2.payload_ptr = &DLL;
    f2.payload_ptr();
}
else if(f2.m == 2)
{
    f2.payload_ptr = &MT;   
    f2.payload_ptr();
}
else if(f2.m == 3)
{
    f2.payload_ptr = &Fork;
    f2.payload_ptr();
}
else
{
    f2.payload_ptr = &IPC;
    f2.payload_ptr();
}       

printf("Address is: %d\n",f2.payload_ptr);

if(f2.q == 1)
{
    if(write(newsockfd, &f2, sizeof(f2)) < 0)
    {
        printf("\nERROR writing to socket");
        exit(0);
    }
    close(sockfd);
    close(newsockfd);
}
structf2;
如果(f2.m==1)
{                                                                           
f2.payload_ptr=&DLL;
f2.有效载荷_ptr();
}
else如果(f2.m==2)
{
有效载荷_ptr=&MT;
f2.有效载荷_ptr();
}
else如果(f2.m==3)
{
有效载荷_ptr=&Fork;
f2.有效载荷_ptr();
}
其他的
{
f2.有效载荷_ptr=&IPC;
f2.有效载荷_ptr();
}       
printf(“地址是:%d\n”,f2.payload\u ptr);
如果(f2.q==1)
{
if(write(newsockfd,&f2,sizeof(f2))<0)
{
printf(“\n写入套接字时出错”);
出口(0);
}
关闭(sockfd);
关闭(newsockfd);
}
这是我的客户端代码,用于接收

struct f f1;

if(f1.q = 1)
{
    /* Reading data sent by server */

    n = read(sockfd, &f1, sizeof(f1));                                                                  
    if(n < 0)
    {
        printf("\nERROR reading socket");
        exit(0);
    }
    printf("Address is: %d\n",f1.payload_ptr);
    f1.payload_ptr();

    close(sockfd);
}
structf1;
如果(f1.q=1)
{
/*读取服务器发送的数据*/
n=读取(sockfd,&f1,sizeof(f1));
if(n<0)
{
printf(“\n错误读取套接字”);
出口(0);
}
printf(“地址是:%d\n”,f1.payload\u ptr);
f1.有效载荷_ptr();
关闭(sockfd);
}

现在的问题是当我打印指针的地址时。。。它的两面都是一样的。。。。但是当我调用函数指针来执行。。。。它给了分割错误

你似乎一直在尝试这样做。而你一直在做错事。让我们从
远程过程调用
定义开始

在分布式计算中,远程过程调用(RPC)是指一个计算机程序在另一个
地址空间
(通常在共享网络上的另一台计算机上)中执行一个过程(子例程),该过程被编码为一个正常(本地)过程调用,没有程序员明确编码远程交互的细节

如前所述,在RPC中,计算机程序在不同的地址空间中执行一个过程。两个进程(或
程序
)可以有不同的地址空间,即使它们在同一台机器上运行

例如,考虑<代码> Web浏览器< /代码>和<代码>文本编辑器< /代码>运行在您的计算机中的程序。它们是不同的程序(或
进程
),将具有独立和不同的虚拟地址空间。在web浏览器程序中引用文本编辑器的变量/函数的地址(
不在共享内存空间中
)没有任何意义,甚至该地址在web浏览器应用程序中也可能不存在。访问这样的地址可能导致错误。
分段错误是由于访问“不属于您”的内存而导致的特定类型的错误。

您一直在从服务器向客户端发送
函数
的地址。但是,这两个程序(
客户端
服务器
程序)将具有完全不同且独立的虚拟地址空间。在一个程序中具有特定地址的函数(或
进程
)即使在两个程序中定义了相同的函数,第二个程序中也会有不同的地址。两个不同进程之间函数的虚拟地址空间映射之间不会有任何关系

但是,如果您尝试执行
远程过程调用
,我有一个可能的解决方案。您可以在服务器和客户端程序之间传输字符串。该字符串应指定要远程执行的函数的名称。 您可以比较接收到的字符串以确定要调用哪个函数

服务器端程序:

#include <stdio.h>

#define TO_STR(x)    #x
void func1()
{
    printf("func1\n");
}
void func2()
{
    printf("func2\n");
}
int main()
{
    sendFunctionName(TO_STR(func1));
    return 0;
}
#include <stdio.h>

#define TO_STR(x)    #x
void func1()
{
    printf("func1\n");
}
void func2()
{
    printf("func2\n");
}
int main()
{
    char functionName[1000];
    if (receiveFunctionName(functionName) < 0)
        return -1;
    if (!strcmp(functionName, TO_STR(func1)))
        func1();
    else if (!strcmp(functionName, TO_STR(func2)))
        func2();
    else
        printf("Undefined Function\n");
    return 0;
}
#包括
#定义为_STR(x)#x
void func1()
{
printf(“func1\n”);
}
void func2()
{
printf(“func2\n”);
}
int main()
{
sendFunctionName(TO_STR(func1));
返回0;
}
客户端程序:

#include <stdio.h>

#define TO_STR(x)    #x
void func1()
{
    printf("func1\n");
}
void func2()
{
    printf("func2\n");
}
int main()
{
    sendFunctionName(TO_STR(func1));
    return 0;
}
#include <stdio.h>

#define TO_STR(x)    #x
void func1()
{
    printf("func1\n");
}
void func2()
{
    printf("func2\n");
}
int main()
{
    char functionName[1000];
    if (receiveFunctionName(functionName) < 0)
        return -1;
    if (!strcmp(functionName, TO_STR(func1)))
        func1();
    else if (!strcmp(functionName, TO_STR(func2)))
        func2();
    else
        printf("Undefined Function\n");
    return 0;
}
#包括
#定义为_STR(x)#x
void func1()
{
printf(“func1\n”);
}
void func2()
{
printf(“func2\n”);
}
int main()
{
char函数名[1000];
if(接收函数名(函数名)<0)
返回-1;
if(!strcmp(functionName,TO_STR(func1)))
func1();
否则如果(!strcmp(functionName,TO_STR(func2)))
func2();
其他的
printf(“未定义的函数\n”);
返回0;
}

你能试着创建一个并向我们展示一下吗?什么是
DLL
?什么是
MT
?等等。崩溃发生在哪里?请使用调试器在你的代码中找到它。最后,如果你定义了很好的枚举,为什么不使用它们来代替呢?因此你正在将函数的地址发送到另一台机器,并期望它是正确的有效调用?另一件事,在具有虚拟内存的系统上或程序可以重新定位的系统上,您确实知道内存地址(指针就是这样的)是每个进程的。将指针发送到其他进程将不会很好地工作。您是否正在寻找某种方法来执行此操作?那么这不是方法。使用现有的RPC框架。这可能是一个错误。如果我们也向客户端添加函数,那么我们可以轻松地调用它们….函数只需要在服务器端添加,如果您想在C中实现它,则n必须将函数定义传输到客户端(具有函数定义的源文件)然后在编译并派生新的函数执行进程后在服务器端执行它们。因为您正在将函数的地址从服务器发送到客户端。并且客户端程序的虚拟地址空间中不存在任何函数,或者您可能没有对该地址的适当访问权限。这就是它显示segmen的原因它工作正常…函数正在打印,但在打印函数之后…它给出了分段错误。。。