函数指针执行出错

时间:2016-10-28 09:30:44

标签: 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;
    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);
}

这是我接收的客户端代码..

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);
}

现在的问题是当我打印那个指针的地址时...它在两边打印相同....但是当我调用该函数指针执行....它给出分段错误

1 个答案:

答案 0 :(得分:1)

好像你一直试图做Remote Procedure Call。你做错了。让我们从Remote Procedure Call定义开始。

  

在分布式计算中,远程过程调用(RPC)是指计算机程序导致过程(子例程)在另一个address space中执行(通常在共享网络上的另一台计算机上),其编码就像它一样是一个正常的(本地)过程调用,没有程序员明确编写远程交互的细节。

因为,提到在RPC中,计算机程序在不同的地址空间中执行过程。两个进程(或program)可以具有不同的地址空间,即使它们在同一台机器上运行。

例如,考虑在您的计算机上运行的web browsertext editor程序。它们是不同的程序(或processes),并且将具有独立且不同的虚拟地址空间。在Web浏览器程序中引用文本编辑器的变量/函数的地址(not in shared memory space)没有任何意义,甚至该地址甚至可能不会退出Web浏览器应用程序。访问此类地址可能会导致Segmentation FaultSegmentation fault is a specific kind of error caused by accessing memory that “does not belong to you"

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

但如果您尝试Remote Procedure Call,我可以为您的问题找到解决方法。您可以在服务器和客户端程序之间转换字符串。该字符串应指定要远程执行的函数的名称。 您可以比较收到的字符串以确定要调用的函数。

服务器端程序:

#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;
}