【问题标题】:Simple calculator with rpcgen带有 rpcgen 的简单计算器
【发布时间】:2013-10-07 04:15:08
【问题描述】:

我是 C 编程的新手。我尝试创建一个小而简单的程序来将文件 calculs.x 中的两个整数相加

这里是calculs.x文件的内容

/* calculs.x*/

struct data_in {
    int arg1;
    int arg2;
};
typedef struct data_in data_in;

struct result_int {
    int result;
    int errno;
};

struct result_float {
    int result;
    int errno;
};

typedef struct result_int result_int;
typedef struct result_float result_float;

program CALCULS{
    version VERSION_UN{
        void CALCULS_NULL(void) = 0;
        result_int ADD (data_in) = 1;
        result_int SUB(data_in) = 2;
        result_int MUL(data_in) = 3;
        result_float DIV (data_in) = 4;
    } = 1;
} = 0x20000001;

我第一次为客户创建了一个文件 calculs.c:

#include <rpc/rpc.h>
#include "calculs.h"

int main(int argc, char *argv[]) {
    int buffer[256];
    struct data_in input;
    struct result_int *output;
    CLIENT *cl;

    if (argc != 2) {
        printf("usage: client hostname_of_server\n");
        exit(1);
    }

    /*Etablir le lien vers le serveur distant
     * cl = clnt_create(server, PROG, VERS, prot);
     */
    cl = clnt_create(argv[1], CALCULS, VERSION_UN, "tcp");
    if (cl == NULL) {
        clnt_pcreateerror(argv[1]);
        exit(1);
    }

    input.arg1 = 5;
    input.arg2 = 5;

    output = add_1(&input, cl);
    if (output == NULL) {
        clnt_perror(cl, argv[1]);
        exit(1);
    }
    printf("the result field is %d\n", output->result);
    printf("the errno field is %d\n", output->errno);

    clnt_destroy(cl);

    return 0;
}

我在编译这个文件时没有收到任何错误,但是对于另一个 rcalculs.c 文件,我无法编译。这是文件内容rcalculs.c:

#include <rpc/rpc.h>
#include "calculs.h"

result_int *add_1(struct data_in data, struct svc_req *rqstp) {
    int buffer;
    struct result_int result;
    int a = data.arg1;
    int b = data.arg2;
    buffer = a+b;
    result.result = buffer;
    result.errno =0;
    return result;
}

编译报错是

rcalculs.c:11:13: erreur: conflicting types for ‘add_1’
In file included from rcalculs.c:9:0:
calculs.h:46:22: note: previous declaration of ‘add_1’ was here
rcalculs.c: In function ‘add_1’:
rcalculs.c:19:5: erreur: incompatible types when returning type ‘struct result_int’ but ‘struct result_int *’ was expected

您能帮我解决这个问题吗?

【问题讨论】:

    标签: c linux calculator


    【解决方案1】:

    按如下方式使用您的 calculs.x。

    /* calculs.x*/
    
    struct data_in {
        int arg1;
        int arg2;
    };
    typedef struct data_in data_in;
    
    struct result_int {
        int result;
        int errno;
    };
    
    struct result_float {
        int result;
        int errno;
    };
    
    typedef struct result_int result_int;
    typedef struct result_float result_float;
    
    program CALCULS{
        version VERSION_UN{
            void CALCULS_NULL(void) = 0;
            result_int ADD (data_in) = 1;
            result_int SUB(data_in) = 2;
            result_int MUL(data_in) = 3;
            result_float DIV (data_in) = 4;
        } = 1;
    } = 0x20000001;
    

    对于您的客户 calculs.c 用户

    #include <rpc/rpc.h>
    #include "calculs.h"
    
    result_int *add_1(struct data_in data, struct svc_req *rqstp);
    
    int main(int argc, char *argv[]) {
        int buffer[256];
        struct data_in input;
        struct result_int *output;
        CLIENT *cl;
    
        if (argc != 2) {
            printf("usage: client hostname_of_server\n");
            exit(1);
        }
    
        /*Etablir le lien vers le serveur distant
         * cl = clnt_create(server, PROG, VERS, prot);
         */
        cl = clnt_create(argv[1], CALCULS, VERSION_UN, "tcp");
        if (cl == NULL) {
            clnt_pcreateerror(argv[1]);
            exit(1);
        }
    
        input.arg1 = 5;
        input.arg2 = 5;
    
        output = add_1(&input, cl);
        if (output == NULL) {
            clnt_perror(cl, argv[1]);
            exit(1);
        }
        printf("the result field is %d\n", output->result);
        printf("the errno field is %d\n", output->errno);
    
        clnt_destroy(cl);
    
        return 0;
    }
    

    rcalculs.c 的内容:

    #include <rpc/rpc.h>
    #include "calculs.h"
    
    result_int *add_1(struct data_in data, struct svc_req *rqstp) {
        int buffer;
        struct result_int result;
        int a = data.arg1;
        int b = data.arg2;
        buffer = a+b;
        result.result = buffer;
        result.errno =0;
        return &result;
    }
    

    让我知道它是否有效。

    【讨论】:

      【解决方案2】:
      erreur: conflicting types for ‘add_1
      

      这个错误是因为你没有声明 add_1() 函数。并且当您对 add_1() 进行函数调用时,它会将其视为声明。

      main()之前添加这一行

        result_int *add_1(struct data_in data, struct svc_req *rqstp);
      

      rcalculs.c:19:5: erreur: 当返回类型‘struct result_int’但期望‘struct result_int *’时类型不兼容

        result_int * add_1(struct data_in data, struct svc_req *rqstp) {
          int buffer;
          struct result_int result; //here declare pointer
          int a = data.arg1;
          int b = data.arg2;
          buffer = a+b;
          result.result = buffer; //change here
          result.errno =0;        //change here 
          return result; //here you are returning struct result_int type but required is struct result_int * type 
         }
      

      返回指针。并在您的功能中进行相应的更改。


      output = add_1(&input, cl); //here you are passing reference of input but you just need to pass input.
      

      【讨论】:

        【解决方案3】:

        当您说时,您将函数 add_1 定义为返回指向 result_int 的指针

        result_int *add_1(struct data_in data, struct svc_req *rqstp) {
        

        在您的文件中rcalculs.c

        但是,在你定义的那个函数里面

        struct result_int result;
        

        当你返回一个值时,你会这样做

        return result;
        

        如果您不希望出现错误,则必须这样做

        return &result;
        

        问题在于您的 result 变量是在函数内部(在堆栈上)本地创建的 - 因此一旦函数返回,它将变得无效。一个快速而丑陋的“修复”是将您的变量定义为static(这意味着1-在函数返回后它将继续存在,但2-您的函数不再是线程安全的:如果它从两个不同的地方不知道会引用什么值)。

        您没有发布您的.h 文件,所以我猜测了一下,但我认为对rcalculs.c 的以下更改将“解决”您的问题(但请注意上面的评论......这不是很好编程实践)

        #include <rpc/rpc.h>
        #include "calculs.h"
        
        result_int *add_1(struct data_in data, struct svc_req *rqstp) {
            int buffer;
            static struct result_int result;
            int a = data.arg1;
            int b = data.arg2;
            buffer = a+b;
            result.result = buffer;
            result.errno =0;
            return &result;
        }
        

        让我知道这是否有效。注意 - 这只是为了帮助您理解错误 - 我不建议将其作为“真实”程序的程序结构。

        好机会!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多