我试图用C ++制作C包装器。
但我无法将类中的函数转换为结构函数指针。
myCallback函数不应该用作静态函数,因为它必须被覆盖。
以下是示例代码:
#include <iostream>
extern "C" {
typedef struct _client_config
{
void (*on_connect)(void *client, int result);
} client_config;
}
class Parent
{
public:
Parent() {};
~Parent() {};
virtual void myCallback(void* hello, int world) = 0;
};
class Child : public Parent
{
public:
Child() {};
~Child() {};
void myCallback(void* hello, int world)
{
printf("Hello World! \n");
}
};
int main(void)
{
Parent* myClass = new Child();
client_config* myClientConfig = (client_config *)malloc(sizeof(client_config));
myClientConfig->on_connect = myClass->myCallback;
return 0;
}
以下是编译器在编译期间所说的内容:
Error 1 error C3867: 'Parent::myCallback': function call missing argument list; use '&Parent::myCallback' to create a pointer to member
Error 2 error C2440: '=' : cannot convert from 'void (__thiscall Parent::* )(void *,int)' to 'void (__cdecl *)(void *,int)'
有人能指出一种方法将类成员函数绑定到结构函数指针或我在这里做错了吗?
答案 0 :(得分:1)
C库的函数指针仅与<select class="form-control" name="properties" type="text" class="form-control" required>
<?php
$prop = $_GET['properties'];
$sql = "SELECT `id`
FROM '".$prop."' ORDER BY `id` ASC";
$result = $DB_CON_C->query($sql);
?>
</select>
自由函数兼容。 (即使静态成员函数不兼容,语言链接也是错误的。)
您必须使用蹦床这样的功能,询问您收到指向对象所在位置的指针的对象(该库确实提供了一种存储某种形式的用户数据的方法,可以检索在回调中,不是吗?也许extern "C"
参数是这样的,你必须阅读文档。),强制转换为client
,然后执行成员调用。编译器不会为你做这件事。
Parent*
通常对C ++库进行编码以使其更容易,例如通过接受可以携带其自身状态的extern "C" void connect_trampoline( void* client, int result )
{
Parent* my_object = static_cast<Parent*>(client);
my_object->myCallback(result);
}
myClientConfig->on_connect = &connect_trampoline;
。但是在C编程风格中,C库使用的是你必须找到你的对象并在使用成员之前做一个丑陋的演员。
如果库没有在您的控件下使某种形式的指针可以被回调访问,但确实传递了指向与回调相关联的库对象的指针,则可以使用全局{ {1}}查找您的对象。这种方法也避免了演员。
当你把指向你的对象的指针移到你想要的库时要小心,你给它提供了相同的确切类型(在这种情况下为std::function
),你将在以后回放它。如果你给std::map<library_object*, Parent*>
,效果就是做Parent*
非常糟糕。 (Derived*
到reinterpret_cast<Parent*>(p_derived)
,当你把它指向库时,static_cast
到void*
,当你找回它时,C ++标准说这个序列与static_cast
)