Как работают иконки Webfont
Значки Webfonts работают с помощью CSS для вставки определенного глифа в HTML с использованием свойства content. Затем он использует @ font-face для загрузки веб-сайта dingbat, который стилирует введенный глиф. Результатом является то, что введенный глиф становится желаемым значком.
Для начала вам понадобится файл webfont с нужными значками, либо определенный для определенных символов ASCII (A, B, C,!, @, # и т. д.) или в области частного использования шрифта Unicode, которые являются пробелами в шрифте, которые не будут использоваться конкретными символами в кодированном кодировке Unicode.
blockquote>Здесь вы можете прочитать, как создать значок webfont -> link
Вы можете сделать это, если функция-член является статической.
Нестатические функции-члены класса A имеют неявный первый параметр типа class A *
, который соответствует этому указателю. Вот почему вы могли зарегистрировать их только в том случае, если в сигнатуре обратного вызова также был первый параметр типа class A *
.
В этом решении у нас есть шаблонный класс со статическим методом, который будет дан "c функция" как обратный вызов. Этот класс содержит "обычный" объект (с функцией членства, названной обратным вызовом (), который наконец назовут).
, Как только Ваш класс (здесь, A) определяется, он может легко использоваться:
int main() {
Holder<A> o ( A(23, 23) );
std::cout << o().getN() << "\n";
callACFunctionPtr( fun );
callACFunctionPtr( o.callback );
} // ()
Полный пример:
#include <iostream>
// ----------------------------------------------------------
// library class: Holder
// ----------------------------------------------------------
template< typename HeldObjectType >
class Holder {
public:
static inline HeldObjectType object;
static void callback( ) {
object.callback();
} // ()
HeldObjectType & operator() ( ) {
return object;
}
Holder( HeldObjectType && obj )
{
object = obj;
}
Holder() = delete;
}; // class
// ----------------------------------------------------------
// "old" C function receivin a ptr to function as a callback
// ----------------------------------------------------------
using Callback = void (*) (void);
// ..........................................................
// ..........................................................
void callACFunctionPtr( Callback f ) {
f();
} // ()
// ----------------------------------------------------------
// ----------------------------------------------------------
void fun() {
std::cout << "I'm fun\n";
} //
// ----------------------------------------------------------
//
// Common class where we want to write the
// callback to be called from callACFunctionPtr.
// Name this function: callback
//
// ----------------------------------------------------------
class A {
private:
int n;
public:
A( ) : n( 0 ) { }
A( int a, int b ) : n( a+b ) { }
void callback( ) {
std::cout << "A's callback(): " << n << "\n";
}
int getN() {
return n;
}
}; // class
// ----------------------------------------------------------
// ----------------------------------------------------------
int main() {
Holder<A> o ( A(23, 23) );
std::cout << o().getN() << "\n";
callACFunctionPtr( fun );
callACFunctionPtr( o.callback );
} // ()
Проблема в том, что метод! = Функция. Компилятор преобразует ваш метод в нечто подобное:
int e( A *this, int *k, int *j );
Итак, он уверен, что вы не можете передать его, потому что экземпляр класса не может быть передан в качестве аргумента. Один из способов обойти эту проблему - сделать метод статическим, чтобы у него был хороший тип. Но не будет никакого экземпляра класса и доступа к нестатическим членам класса.
Другой способ - объявить функцию со статическим указателем на A, инициализированным в первый раз. Функция только перенаправляет вызов в класс:
int callback( int *j, int *k )
{
static A *obj = new A();
a->(j, k);
}
Затем вы можете зарегистрировать функцию обратного вызова.
Ну ... если вы используете платформу win32, всегда есть неприятный способ Thunking ...
Thunking в Win32: упрощение обратных вызовов для нестатических функций-членов
Это решение, но я не рекомендую его использовать.
У этого есть хорошее объяснение, и приятно знать, что оно существует.
Проблема с использованием функции-члена заключается в том, что ей нужен объект, с которым можно действовать, а C не знает об объектах.
Самый простой способ - это сделать следующее:
//In a header file:
extern "C" int e(int * k, int * e);
//In your implementation:
int e(int * k, int * e) { return 0; }