Как правильно инициализировать строку, которая является полем автоматически сгенерированной структуры из RPC в ANSI-C - PullRequest
0 голосов
/ 04 января 2019

Я программирую клиент-серверное приложение RPC, используя ANSI-C, в Ubuntu 17.04. У меня большие проблемы во время правильной инициализации строк, которые автоматически генерируются из предопределенных структур с использованием 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>;
};

Здесь определение удаленной функции (в RPC):

program NPROG {
 version NVERS {
  string registrarse(usuario)=2;
 }=1;
}=0x20000001;

ПРИМЕЧАНИЕ. Я инициализирую все поля и все строки перед удаленным вызовом, строки, как показано ниже, но здесь я пишу только одно, чтобы не писать длинный вопрос.

Теперь у меня что-то вроде этого на стороне клиента:

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 */
} 

Я не ставлю код удаленного сервера, потому что даже не могу туда добраться.

1 Ответ

0 голосов
/ 04 января 2019

Проблема в том, что в сгенерированной структуре для строк память не выделяется заранее, это просто висячие указатели! Таким образом, вы должны заботиться о памяти для строки самостоятельно, например, вы можете передать константу:

register_arg.nombreUsuario = "SomeName";

или выделите память самостоятельно:

register_arg.nombreUsuario = strdup("SomeName");

Тогда все должно работать так, как вы ожидаете.

...