Это позаботится о добавлении элемента в пустой DataFrame. Проблема в том, что df.index.max () == nan для первого индекса:
df = pd.DataFrame(columns=['timeMS', 'accelX', 'accelY', 'accelZ', 'gyroX', 'gyroY', 'gyroZ'])
df.loc[0 if math.isnan(df.index.max()) else df.index.max() + 1] = [x for x in range(7)]
Вы не можете напрямую передать указатель на объект-объект C ++ как указатель на код C (или даже на код C ++).
Кроме того, чтобы переносить обратный вызов на код C, он должен быть по крайней мере, объявлен как функция extern "C"
non-member. По крайней мере, поскольку некоторые API требуют специальных соглашений о вызовах функций и, таким образом, дополнительных модификаторов деклараций.
Во многих средах C и C ++ имеют одинаковые соглашения о вызовах и отличаются только именем, так что любая глобальная функция или статический член Работа. Но вам все равно нужно обернуть вызов operator()
в нормальной функции.
class MyFunctor {
// no state
public:
MyFunctor();
int operator()(SomeType ¶m) const;
}
вы можете написать нормальную внешнюю функцию «C», которая создает функтор и выполняет свой оператор (). extern "C" int MyFunctorInC(SomeType *param)
{
static MyFunctor my_functor;
return my_functor(*param);
}
class MyFunctor {
// Some fields here;
public:
MyFunctor(/* some parameters to set state */);
int operator()(SomeType ¶m) const;
// + some methods to retrieve result.
}
, а функция обратного вызова C принимает какой-то параметр состояния пользователя (обычно void *): void MyAlgorithmInC(SomeType *arr,
int (*fun)(SomeType *, void *),
void *user_state);
вы можете написать обычный экстент «C ", которая передает свой параметр состояния объекту-функтору: extern "C" int MyFunctorInC(SomeType *param, void *user_state)
{
MyFunctor *my_functor = (MyFunctor *)user_state;
return (*my_functor)(*param);
}
и использует его следующим образом: MyFunctor my_functor(/* setup parameters */);
MyAlgorithmInC(input_data, MyFunctorInC, &my_functor);
Я нашел этот «g0] gem » с помощью google. Видимо, возможно, но я бы не рекомендовал его. Прямая ссылка в пример исходного кода.
Нет, конечно. Подпись вашей функции C принимает аргумент как функцию.
void f(void (*func)())
{
func(); // Only void f1(), void F2(), ....
}
Все трюки с функторами используются функциями шаблона:
template<class Func>
void f (Func func)
{
func(); // Any functor
}
Хм, возможно, вы могли бы написать бесплатную функцию шаблона, которая обертывает ваши объекты-функции. Если все они имеют одну и ту же подпись, это должно работать. Как это (не проверено):
template<class T>
int function_wrapper(int a, int b) {
T function_object_instance;
return funcion_object_instance( a, b );
}
Это будет делать для всех функций, которые принимают два int и возвращают int.
Я бы сказал «нет», потому что у функтора C ++ есть перегруженный оператор ()
, который является функцией -члена и поэтому требует указателя функции-члена. Это совершенно другой тип данных, чем обычный указатель функции C, поскольку он не может быть вызван без экземпляра класса. Вам нужно будет передать нормальную функцию или статическую функцию-член в библиотеку C. Поскольку перегруженный оператор ()
не может быть статическим, вы не можете этого сделать. Вам нужно будет передать C-библиотеке нормальную, не-членную функцию или статическую функцию-член, из которой вы затем можете вызвать функтор C ++.
Функция обратного вызова C, написанная на C ++, должна быть объявлена как функция extern "C"
- поэтому использование функтора напрямую отсутствует. Вам нужно будет написать какую-то функцию обертки для использования в качестве этого обратного вызова, и эта оболочка вызовет функтор. Конечно, протокол обратного вызова должен иметь некоторый способ передачи контекста функции, чтобы он мог добраться до функтора, или задача становится довольно сложной. Большинство схем обратного вызова имеют способ передать контекст, но я работал с некоторыми мертвыми мозгами, которые этого не делают.
См. Этот ответ для получения более подробной информации (и посмотрите в комментариях для анекдотических доказательств того, что обратный вызов должен быть extern "C"
, а не только статической функцией-членом):
Многие API-интерфейсы C, которые выполняют обратные вызовы функции-указателя, имеют параметр void * для состояния пользователя. Если у вас есть один из них, вам повезло - вы можете использовать функцию exterm C, которая обрабатывает пользовательские данные как своего рода ссылку или ключ для поиска функтора, а затем выполняет его.
В противном случае нет.
Это зависит, если это статический или экземплярный метод, если он статичен, то вы можете пройти через функцию как className :: functionName, если это метод экземпляра, это будет более сложным, потому что вам, очевидно, нужно связать определенный экземпляр, но не может сделать это так же, как с делегатами на C # и т. д.
. Лучший способ, который я нашел, - создать класс хранения, который создается с помощью экземпляр объекта, а также указатель функции, класс удержания может затем вызвать функцию напрямую.
Я не думаю, что вы можете: operator()
в объекте функции действительно является функцией-членом, а C ничего не знает об этом.
То, что вы должны использовать, бесплатное C ++ или статические функции классов.
GCC позволяет конвертировать указатели на функции функций в простые указатели функций (первый аргумент функции, называемый указателем простой функции, затем this
).
Проверьте соответствующую ссылку в руководстве .
Для этого требуется флаг -Wno-pmf-conversions
, чтобы отключить соответствующее предупреждение для явно нестандартной функции. Очень удобно для взаимодействия библиотек стилей C с программированием на языке C ++. Когда указатель на функцию-член является константой, это даже не нужно генерировать код вообще: API будет использовать этот аргумент в любом случае.
Если у вас уже есть функтор, сглаживание функтора таким образом скорее всего, означает сглаживание его operator()
, предоставляя вам функцию, которую нужно вызвать с помощью указателя класса функтора в качестве первого аргумента. Который не всегда помогает в этом, но, по крайней мере, имеет C-связь.
Но по крайней мере, когда вы не проходите через функторы, это полезно и обеспечивает замену ссылки на C для std::mem_fn
с <functional>
.