Если Вы надеетесь обнаруживать non-UTF кодировку (т.е. никакой BOM), Вы в основном до эвристики и статистического анализа текста. Вы могли бы хотеть смотреть на документ Mozilla об обнаружении универсального набора символов ( та же ссылка с лучшим форматированием с помощью Wayback Machine ).
Вы не можете напрямую передать указатель на объект функтора C ++ как указатель функции на код C (или даже в код C ++).
Кроме того, для переносимой передачи обратного вызова в код C он должен быть как минимум объявлен
как extern «C»
функция, не являющаяся членом.
По крайней мере, потому что некоторые API требуют определенных соглашений о вызове функций и, следовательно,
дополнительные модификаторы объявления.
Во многих средах C и C ++ имеют одинаковые соглашения о вызовах и отличаются только
при изменении имени, поэтому любая глобальная функция или статический член будет работать.
Но вам все равно нужно обернуть вызов operator ()
в обычную функцию.
Если ваш функтор не имеет состояния (это объект, просто чтобы удовлетворить некоторые формальные требования и т. д.):
class MyFunctor {
// нет состояния
общественность:
MyFunctor ();
int оператор () (SomeType & param) const;
}
вы можете написать обычную функцию extern "C", которая создает функтор и выполняет его operator ().
extern "C" int MyFunctorInC (SomeType * param)
{
статический MyFunctor my_functor;
return my_functor (* параметр);
}
Если у вашего функтора есть состояние, например:
class MyFunctor {
// Здесь несколько полей;
общественность:
MyFunctor (/ * некоторые параметры для установки состояния * /);
int оператор () (SomeType & param) const;
// + несколько методов для получения результата.
}
и функция обратного вызова C принимает какой-то параметр состояния пользователя (обычно void *):
void MyAlgorithmInC (SomeType * arr,
int (* весело) (SomeType *, void *),
void * user_state);
вы можете написать обычную внешнюю функцию «C», которая преобразует свой параметр состояния в ваш объект-функтор:
extern "C" int MyFunctorInC (SomeType * param, void * user_state)
{
MyFunctor * my_functor = (MyFunctor *) user_state;
return (* my_functor) (* параметр);
}
и используйте его так:
MyFunctor my_functor (/ * параметры настройки * /);
MyAlgorithmInC (input_data, MyFunctorInC, & my_functor);
В противном случае это единственный нормальный способ сделать это (нормально, как "без генерации машинного кода во время выполнения" и т. д.) заключается в использовании некоторого статического (глобального) или локального хранилища потока для передачи функтора к внешней функции "C". Это ограничивает то, что вы можете делать со своим кодом, и некрасиво, но будет работать.
Я нашел этот « драгоценный камень » с помощью Google. По-видимому, возможно, но я бы не рекомендовал это. Прямая ссылка на пример исходного кода.
Нет, конечно. Подпись вашей функции C принимает аргумент как функцию.
void f(void (*func)())
{
func(); // Only void f1(), void F2(), ....
}
Все уловки с функторами используются шаблонными функциями:
template<class Func>
void f (Func func)
{
func(); // Any functor
}
Функция обратного вызова AC, написанная на C ++, должна быть объявлена как функция extern «C»
, поэтому прямое использование функтора невозможно. Вам нужно будет написать какую-то функцию-оболочку для использования в качестве этого обратного вызова и заставить эту оболочку вызывать функтор. Конечно, протокол обратного вызова должен иметь некоторый способ передачи контекста функции, чтобы она могла добраться до функтора, иначе задача станет довольно сложной. У большинства схем обратного вызова есть способ передать контекст, но я работал с некоторыми бездумными, которые этого не делают.
См. Этот ответ для получения дополнительной информации (и посмотрите в комментариях неофициальные доказательства того, что обратный вызов должен быть extern «C»
, а не только статическая функция-член):
Я не думаю, что вы можете: operator ()
в объекте функции действительно является функцией-членом, а C ничего не знает о них.
Вы должны уметь использовать бесплатные функции C ++ или статические функции классов.
Это зависит от того, статический ли это метод или метод экземпляра, если он статический, тогда вы можете передать функцию как className :: functionName, если это метод экземпляра, это будет более сложным, потому что вам, очевидно, нужно привязаться к определенному экземпляру, но вы не можете сделать это так же, как с делегатами в C # и т. д.
Наилучший способ, который я нашел для этого, - создать удерживающий класс, который является создаваемый экземпляром объекта, а также указателем на функцию, удерживающий класс может затем напрямую вызывать функцию.
Я бы сказал нет, потому что функтор C ++ имеет перегруженный оператор ()
, который является функцией-членом , и, следовательно, для него потребуется указатель на функцию-член. Это совершенно другой тип данных, чем обычный указатель на функцию C, поскольку он не может быть вызван без экземпляра класса. Вам нужно будет передать обычную функцию или статическую функцию-член в библиотеку C. Поскольку перегруженный оператор ()
не может быть статическим, вы не можете этого сделать. Вам нужно будет передать C-библиотеку обычным образом,
Хм, может быть, вы могли бы написать бесплатную функцию-шаблон, которая обтекает ваши объекты-функции. Если все они имеют одинаковую подпись, это должно сработать. Примерно так (не проверено):
template<class T>
int function_wrapper(int a, int b) {
T function_object_instance;
return funcion_object_instance( a, b );
}
Это применимо для всех функций, которые принимают два целых числа и возвращают целое число.
Многие API-интерфейсы C, которые принимают обратные вызовы указателя функций, имеют параметр void * для состояния пользователя. Если у вас есть один из них, вам повезло - вы можете использовать функцию exterm C, которая обрабатывает данные пользователя как своего рода ссылку или ключ для поиска функтора, а затем выполняет его.
В противном случае - нет.