2010-09-17 2 views
1

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

int copy_key__sint_(void *key, void **args, int argc, void **out {
if ((*out = malloc(sizeof(int))) {
return 1;
}

**((_int_ **) out) = *((_int_ *) key); 
return 0; 

}

Идея заключается в том, что я мог бы назвать макрос, GENERATE_FUNCTIONS («ИНТ», «синт») или что-то вроде этого, и сгенерировать эту функцию. Курсивные части - это то, что необходимо подключить.

Возможно ли это?

ответ

2

Я не понимаю пример функции, которую вы даете очень хорошо, но использование макросов для задачи относительно просто. Только ты не дал бы строки в макрос в качестве аргументов, но маркеры:

#define DECLARE_MY_COPY_FUNCTION(TYPE, SUFFIX)    \ 
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) 

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)    \ 
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) { \ 
/* do something with TYPE */        \ 
return whatever;           \ 
} 

Вы можете затем использовать это, чтобы объявить функции в файле заголовка

DECLARE_MY_COPY_FUNCTION(unsigned, toto); 
DECLARE_MY_COPY_FUNCTION(double, hui); 

и определить их в. c файл:

DEFINE_MY_COPY_FUNCTION(unsigned, toto); 
DEFINE_MY_COPY_FUNCTION(double, hui); 

В этой версии, как указано здесь, вы можете получить предупреждения о лишних `; '. Но вы можете избавиться от них, добавив в макросы объявления-заглушки, как это

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)    \ 
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) { \ 
/* do something with TYPE */        \ 
return whatever;           \ 
}               \ 
enum { dummy_enum_for_copy_function_ ## SUFFIX } 
1

Это должно сработать. Чтобы создать copy_key_sint, используйте copy_key_ ## sint.

Если вы не можете заставить это работать с CPP, напишите небольшую программу на C, которая генерирует исходный файл C.

2

Попробуйте что-то вроде этого (я только проверил компиляцию, но не результат в исполняемом программе):

#include "memory.h" 

    #define COPY_KEY(type, name)         \ 
    type name(void *key, void **args, int argc, void **out) { \ 
     if (*out = malloc(sizeof(type))) {      \ 
     return 1;           \ 
     }              \ 
    **((type **) out) = *((type *) key);      \ 
    return 0;             \ 
    }               \ 

COPY_KEY(int, copy_key_sint) 

Более подробную информацию о субъекте обобщенного программирования в C, прочтите this blog wich contains a few examples, а также this book which contains interesting solutions to the problem for basic data structures and algorithm.

0

Не был бы макросом, который просто принимает sizeof(*key), и вызывает одну функцию, которая использует memcpy, чтобы быть намного более чистым (меньше злоупотребления препроцессором и раздуванием кода), чем создание новой функции для каждого типа, чтобы он мог выполнять собственное назначение, а не memcpy ?

Мое мнение, что вся проблема заключается в вашей попытке применить C++-мышление к C. C имеет memcpy по очень веской причине.

+0

@R .: Я не думаю, что это ответ на вопрос OP. Я понимаю тот код, который он дает как один из примеров того, какие * декларации * он хочет достичь. –

+0

Я думаю, что мой ответ относится к большой категории ситуаций, для которых может потребоваться «C++-шаблоны для C». Часто, если вы понимаете, что можете обрабатывать данные в виде абстрактного байтового массива или частично как таковые с функцией обратного вызова для его обработки (как в 'qsort' и т. Д.), Вы можете написать гораздо более простой и эффективный код C , –

+0

Имеет ли memcpy реализацию Windows? – sadakatsu

Смежные вопросы