Я изучаю динамическую загрузку DLL, но я не понимаю, что это строка
typedef void (*FunctionFunc)();
У меня есть несколько вопросов. Если кто-то сможет ответить на них, я буду благодарен.
typedef
?void
не должно быть имени функции или чего-то еще? Это похоже на анонимную функцию.Итак, я в замешательстве; можете ли вы прояснить мне все это?
typedef
- это языковая конструкция, которая связывает имя с типом.
Вы используете его так же, как и исходный тип, например
typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();
используя их как
myinteger i; // is equivalent to int i;
mystring s; // is the same as char *s;
myfunc f; // compile equally as void (*f)();
Как вы можете видеть, вы можете просто заменить указанное имя с указанным выше определением.
Трудность заключается в указателе на синтаксис и читаемость функций в C и С++, а typedef
может улучшить читаемость таких объявлений. Однако синтаксис уместен, поскольку функции, в отличие от других более простых типов, могут иметь возвращаемое значение и параметры, поэтому иногда длинное и сложное объявление указателя на функцию.
Читаемость может стать действительно сложной с указателями на массивы функций и некоторыми другими более косвенными вариантами.
Чтобы ответить на ваши три вопроса
Почему используется typedef? Для облегчения чтения кода - особенно для указателей на функции или имен структуры.
Синтаксис выглядит нечетным (в указателе на объявление функции)
Этот синтаксис не является очевидным для чтения, по крайней мере, при начале. Использование объявления typedef
вместо этого облегчает чтение
Является ли указатель функции создан для хранения адреса памяти функции?
Да, указатель функции хранит адрес функции. Это не имеет ничего общего с конструкцией typedef
, которая облегчает запись/чтение программы; компилятор просто расширяет определение typedef перед компиляцией фактического кода.
Пример:
typedef int (*t_somefunc)(int,int);
int product(int u, int v) {
return u*v;
}
t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456); // call product() to calculate 123*456
typedef type alias
но с указателями на функции, кажется, только 2 аргумента, typedef type
. По умолчанию псевдоним - имя, указанное в аргументе типа?
typedef
используется для псевдонимов; в этом случае вы используете FunctionFunc
для void(*)()
.
Действительно, синтаксис выглядит странно, посмотрите на это:
typedef void (*FunctionFunc) ( );
// ^ ^ ^
// return type type name arguments
Нет, это просто говорит компилятору, что тип FunctionFunc
будет указателем функции, он не определяет один, например:
FunctionFunc x;
void doSomething() { printf("Hello there\n"); }
x = &doSomething;
x(); //prints "Hello there"
typedef
не объявляет новый тип. у вас может быть много определяемых typedef
имен одного и того же типа, и они не отличаются (например, от перегрузки функций). Существуют некоторые обстоятельства, при которых в отношении того, как вы можете использовать имя, определенное с помощью typedef
имя не совсем эквивалентно тому, как оно определено, но множественные определяемые с помощью typedef
имена для одного и того же, эквивалентны.
Без слова typedef
в С++ объявление объявит переменную FunctionFunc
указателя типа для функции без аргументов, возвращая void
.
В typedef
вместо этого он определяет FunctionFunc
как имя для этого типа.
Если вы можете использовать С++ 11, вы можете использовать ключевое слово std::function
и using
.
using FunctionFunc = std::function<void(int arg1, std::string arg2)>;
using
ключевого слова было бы похоже на typedef std::function<void(int, std::string)> FunctionFunc;
На всякий случай, если кто-то хочет другую оболочку для функций без C ++ 11
#include <stdio.h>
#include <math.h>
/*
To define a new type name with typedef, follow these steps:
1. Write the statement as if a variable of the desired type were being declared.
2. Where the name of the declared variable would normally appear, substitute the new type name.
3. In front of everything, place the keyword typedef.
*/
// typedef a primitive data type
typedef double distance;
// typedef struct
typedef struct{
int x;
int y;
} point;
//typedef an array
typedef point points[100];
points ps = {0}; // ps is an array of 100 point
// typedef a function
typedef distance (*distanceFun_p)(point,point) ; // TYPE_DEF distanceFun_p TO BE int (*distanceFun_p)(point,point)
// prototype a function
distance findDistance(point, point);
int main(int argc, char const *argv[])
{
// delcare a function pointer
distanceFun_p func_p;
// initialize the function pointer with a function address
func_p = findDistance;
// initialize two point variables
point p1 = {0,0} , p2 = {1,1};
// call the function through the pointer
distance d = func_p(p1,p2);
printf("the distance is %f\n", d );
return 0;
}
distance findDistance(point p1, point p2)
{
distance xdiff = p1.x - p2.x;
distance ydiff = p1.y - p2.y;
return sqrt( (xdiff * xdiff) + (ydiff * ydiff) );
}
using FunctionFunc = void (*)();
может быть использован вместо Чуть более понятно, что вы просто объявляете имя для типа (указатель на функцию)