Заменить структуру вхождения моим типом - PullRequest
1 голос
/ 11 августа 2011

Не уверен, что заголовок достаточно наводящий на размышления, но вот что я пытаюсь сделать.

Допустим, у меня есть некоторый код, который я не буду касаться, в основном, скажем, функция, которая заполняет структуру.

Теперь эта структура определена где-то еще, и мне было легко не перетаскивать все это в проект, а просто копировать определение структуры было бы излишним.

Так что я определил новыйstruct только с соответствующими полями, и я пытаюсь отправить ее в функцию, чтобы она была заполнена соответствующими полями.

typedef struct {
 ......
} mytype;

Заголовок функции:

int function_header (struct type1 *p, ....);

Имейте в виду, структура type1 нигде не определена.Есть ли способ злоупотребить препроцессором, чтобы получить что-то подобное?

#define (struct type1) mytype

Одним из решений было бы, я думаю,

#define type1 mytype
#define struct
int function_header (struct type1 *p, ....) {    
#undef struct

..............
}

Но, похоже, немного отсталый

Ответы [ 5 ]

3 голосов
/ 11 августа 2011

Почему вы хотите его переименовать? Просто определите

struct type1 {
    ...
};

в вашем собственном исходном файле, и все готово для стрельбы. (И помните, ноги будут повреждены, если вы не уверены на 100%, что ваше собственное определение приведет к точно той же компоновке в памяти, что и та, которую ожидает библиотека).

1 голос
/ 11 августа 2011

Вы можете определить свою новую структуру, имеющую исходную структуру в качестве первого члена. Пример:

struct mytype {
    struct type1 original;
    int custom_field;
};

Поскольку ISO говорит, что перед первым членом struct не будет заполнения, если у вас есть struct mytype*, он позволяет вам привести его к struct type1* без неопределенного поведения.

Однако у вас возникнут проблемы, если исходный код использует sizeof для обхода массива struct type1 экземпляров, тогда как исходный массив на самом деле состоит из struct mytype экземпляров.

1 голос
/ 11 августа 2011

Прежде всего, будьте осторожны. Вы не можете произвольно удалить поля из оригинала struct и ожидать, что функция «заполнит их». Вы можете определить совместимый struct вашего собственного производства, но он должен содержать точные одинаковые поля в точном том же порядке, иначе могут произойти очень плохие вещи. Затем вы можете отправить экземпляр этой структуры с неинициализированными значениями полей в функцию, и он установит значения в ваши поля, как обычно. Но вы не можете удалить поле и затем ожидать, что функция добавит его обратно.

Конечно, даже если вы определите точную копию struct, вы рискуете всевозможными проблемами, как если бы кто-то изменил другой struct без обновления вашей версии, все сломается. Точно так же все сломается, если ваша декларация будет обновлена ​​без соответствующего обновления, сделанного в исходном struct. Было бы гораздо лучше просто переместить определение исходного struct в файл общего заголовка, который можно включить во все места, где необходимо использовать этот struct. Тогда есть только одно определение, которое все используют.

Но в любом случае, поскольку ваша функция просто ожидает указатель на структуру, вы можете вызывать ее практически любым способом. Просто приведите ваш параметр к void*, как показано здесь:

http://ideone.com/c4qtT

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

0 голосов
/ 11 августа 2011

Из того, что я понял, вы не хотите изменять заголовочный файл, но у вас есть полный доступ к исходному файлу?

Вы писали:

#define type1 mytype
#define struct
int function_header (struct type1 *p, ....) {    
#undef struct

..............
}

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

0 голосов
/ 11 августа 2011

Нет, вы не можете этого сделать.Внешняя функция не «знает» о каких-либо определениях, переопределениях, переопределениях и т. Д. Если вы уменьшаете структуру, есть вероятность, что функция, думая, что записывает в исходную структуру, записывает через границы вашего меньшего размера.struct.

Не делайте этого , если вы действительно действительно не знаете, что делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...