简单的计算器与rpcgen

时间:2013-10-07 04:15:08

标签: c linux calculator

我是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
你可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分: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;
}

让我知道它是否有效。

答案 1 :(得分:0)

您正在将函数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;
}

如果有效,请告诉我。注意 - 这只是为了帮助您理解错误 - 我不建议将其作为“真实”程序的程序结构。

Bonne chance!

答案 2 :(得分:0)

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.