如何正确初始化ANSI-C中RPC自动生成结构的字段字符串

如何正确初始化ANSI-C中RPC自动生成结构的字段字符串,c,string,rpc,ansi-c,C,String,Rpc,Ansi C,我正在Ubuntu 17.04中使用ANSI-C编写一个RPC客户机-服务器应用程序。在正确初始化使用RPC从预定义结构自动生成的字符串并将其从客户端传递到服务器时,我遇到了很大的麻烦 以下是我对RPC中结构的定义: struct usuario{ int codigo; string nombreUsuario<25>; string nombreReal<25>; string apellido1<25>; string ap

我正在Ubuntu 17.04中使用ANSI-C编写一个RPC客户机-服务器应用程序。在正确初始化使用RPC从预定义结构自动生成的字符串并将其从客户端传递到服务器时,我遇到了很大的麻烦

以下是我对RPC中结构的定义:

struct usuario{
   int codigo;
   string nombreUsuario<25>;
   string nombreReal<25>;
   string apellido1<25>;
   string apellido2<25>;
   string clave<25>;
   int num_tarjeta;
   string fechaAlta<10>;
   string fechaBaja<10>;
};
注意:我在远程调用之前初始化了所有字段和所有字符串,这些字符串就像我下面要展示的那样,但我在这里只写了一个,以避免写长问题

现在我的客户端有了类似的东西:

void
nprog_1(char *host)
{
CLIENT *clnt;
char * *result_1;
usuario  register_arg;

#ifndef DEBUG
clnt = clnt_create (host, NPROG, NVERS, "tcp");
if (clnt == NULL) {
    clnt_pcreateerror (host);
    exit (1);
}
#endif  /* DEBUG */



register_arg.codigo = 0;

// In this way, Segment fault, the two functions, strcpy and strncpy
// strcpy(register_arg.nombreUsuario, "SomeName");

strncpy(register_arg.nombreUsuario, "SomeName", sizeof(register_arg.nombreUsuario));

// call failed en registro: RPC: Remote system error
// register_arg.nombreUsuario = "SomeName";

result_1 = registrarse_1(&register_arg, clnt);
if (result_1 == (char **) NULL) {
    clnt_perror (clnt, "call failed en registro");
}

#ifndef DEBUG
clnt_destroy (clnt);
#endif   /* DEBUG */
} 

我没有放置远程/服务器代码,因为我甚至无法到达那里。

问题是,在为字符串生成的结构中,没有预先分配内存,这些只是悬空指针!因此,您必须自己关心字符串的内存,例如,您可以传递一个常量:

register_arg.nombreUsuario = "SomeName";
或者自己分配内存:

register_arg.nombreUsuario = strdup("SomeName");

那么它应该会像你期望的那样工作。

另外,Ubuntu 17.04实际上是LTS版吗?我认为偶数版本16.04和18.04是LTS版本,其他版本是“STS–短期支持”版本。Ubuntu似乎同意-;17.04的EOL是2018-01-13,根据。您可能可以使用usuario寄存器_arg={0};-省略的字段将归零。然后,您可以将字段的子集设置为可选的已知值,或多或少如问题所示。如果这不起作用会产生不可接受的警告,那么可以使用usuario register_arg;memset®ister_arg,'\0',sizeofregister_arg;将所有字节设置为零,然后设置一些非零。@JonathanLeffler是的,这很有效!我使用了usuario寄存器_arg={0}。我知道这个问题与错误的预初始化有关,谢谢。它也有效!如果有人读了这篇文章,请查看问题的评论部分,这里还有另一个答案。
register_arg.nombreUsuario = strdup("SomeName");