Как отправлять и получать адреса памяти через сокет в C? - PullRequest
1 голос
/ 20 февраля 2011

Я хочу отправить / получить адрес памяти через сокет в C. Что у меня есть следующее:

void *ptr = malloc(122); /* So the pointer points to some valid address */
unsigned char *socketData = NULL;

socketData = (unsigned char*)malloc(sizeof(void*));
memset(socketData, 0, sizeof(void*));

/* ??? How to get the memory address - where ptr points to - to socketData ??? */

Я знаю, что способ печати адресов указателей с использованием printf заключается в использовании %p, т.е.

printf("%p", ptr);

Но это печатает, например, 0x0021ef1a. То, что я хочу, это просто следующее: 0021ef1a

А на стороне получателя: как преобразовать полученные байты обратно в void*?

Ах: и код должен работать как для 32-битных систем, так и для 64-битных систем;) Кроме того, код должен компилироваться с использованием -Wall -Werror .... huh

Спасибо за помощь! Хороших выходных, Джонас

Ответы [ 2 ]

6 голосов
/ 20 февраля 2011

Чтобы ответить на ваш вопрос, вы можете преобразовать необработанные данные обратно в указатель, просто скопировав:

void *ptr = malloc(42);
void *ptr2 = NULL;

unsigned char *data = malloc(sizeof(void *));

memcpy(data, &ptr, sizeof(void *));

...

memcpy(&ptr2, data, sizeof(void *));

printf("ptr  = %p\n", ptr);
printf("ptr2 = %p\n", ptr2);

Обратите внимание, что в большинстве случаев отправка указателя на сокеты не имеет большого смысла. Значение указателя будет бесполезным для получателя, если только это не будет тот же процесс, что и отправитель. Каждый процесс будет иметь отдельное виртуальное адресное пространство.

Учитывая ваше предложенное приложение, я бы предложил, чтобы на стороне получателя вы вообще рассмотрели представление этого с указателем, так как оно не будет использоваться в этой форме. Вместо этого, почему бы не хранить его в достаточно большом целочисленном типе?

0 голосов
/ 21 февраля 2011

Если вы хотите отформатировать указатель, как printf(), для отправки на другой хост для отображения, тогда sprintf() может быть правильным подходом:

char dest[100] = "";
snprintf(dest, sizeof dest, "%p", ptr);

Это создает строку фиксированной длины, который может быть обработан на удаленном хосте как таковой.Преимущество этого состоит в том, что он не требует, чтобы принимающий хост знал подробности о размере и формате указателя принимающего хоста.

...