【问题标题】:Error in function pointer execution函数指针执行错误
【发布时间】:2017-03-11 04:08:11
【问题描述】:

这是我定义的结构......

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

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

【问题讨论】:

  • 您能尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们看吗? DLL 是什么? MT 是什么?等等。崩溃发生在哪里?请使用调试器在您的代码中找到它。最后,如果你定义了很好的枚举,为什么不使用它们而不是magic numbers
  • 所以您将函数的 地址 发送到另一台机器并期望它是有效调用?
  • 另一件事,在具有虚拟内存或程序可以重定位的系统上,您确实知道内存地址(即指针)是每个进程。向其他进程发送指针不会很好地工作。
  • 您是否正在寻找某种方式来做RPC (Remote Procedure Call)?那么这不是这样做的方法。使用现有的 RPC 框架。
  • 这可能是XY Problem

标签: c function pointers structure void-pointers


【解决方案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;
}

【讨论】:

  • 如果我们在客户端也添加函数,那么我们可以很容易地调用它们......函数只需要在服务器端添加
  • 如果你想用C实现它,那么你必须将函数定义传输到客户端(源文件具有函数定义),然后在编译和fork一个新进程后在服务器端执行它们函数执行。
  • 因为您将函数的地址从服务器发送到客户端。并且您的客户端程序的虚拟地址空间中不存在任何功能,或者您可能没有对该地址的适当权限访问。这就是它显示分段错误的原因。
  • 运行良好....该功能正在打印,但在打印该功能后....出现分段错误...
猜你喜欢
  • 1970-01-01
  • 2012-01-19
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 2016-02-19
相关资源
最近更新 更多