我正在使用C库开发C++应用程序.我必须向C库发送一个函数指针.
这是我的班级:
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
Ui::MainWindow *ui;
void f(int*);
private slots:
void on_btn_clicked();
};
Run Code Online (Sandbox Code Playgroud)
这是我的on_btn_clicked函数:
void MainWindow::on_btn_clicked()
{
void (MainWindow::* ptfptr) (int*) = &MainWindow::f;
c_library_function(static_cast<void()(int*)>(ptfptr), NULL);
}
Run Code Online (Sandbox Code Playgroud)
C函数应该得到一个指向这样一个函数的指针:void f(int*).但上面的代码不起作用,我无法成功将我的f成员函数转换为所需的指针.
有人可以帮忙吗?
可能的重复:
使用 C++ 类成员函数作为 C 回调函数
我正在使用 C 库 (winpcap) 编写面向对象的库。我需要传递网络数据包到达时调用的回调函数作为函数指针。我想将成员函数指针传递给 winpcap,以保持我的设计面向对象并允许不同的对象接收不同的数据包。然而,据我所知,成员函数有不同的调用约定,因此不能传递给 C 函数。有没有办法来解决这个问题。我对 boost::bind 的实验(除了反复试验之外,我几乎无法使用它)并没有结果。
有没有办法改变成员函数的调用约定?
这是我现在使用的回调函数的定义和实际传递给winpcap的
void pcapCallback( byte* param, const struct pcap_pkthdr* header, const byte* pkt_data );
pcap_loop( adhandle, 0, pcapCallback, NULL );
Run Code Online (Sandbox Code Playgroud)
pcap_loop 只采用函数的名称(目前在全局范围内)。这是函数指针参数(pcap_loop 的第三个参数)的定义。由于这是第三方代码,我无法真正改变它。我必须有一个可以采用这种形式的成员函数:
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *);
Run Code Online (Sandbox Code Playgroud)
据我了解,成员函数将使用 thiscall 而 c 函数指针需要一个 cdecl
我有一个C库函数,需要一个函数指针用于回调,我想传入一个C++成员函数.C++函数修改了一个成员变量,所以我不能使用静态自由函数(如几个类似的帖子所示).我的尝试(如下所示)因编译器错误而失败.
这篇文章最接近我的要求:
如果没有静态函数,我怎么能这样做?谢谢!
test.h
#ifndef TEST_H_
#define TEST_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*handler_t)(int foo, void *bar);
void set_handler(handler_t h);
#ifdef __cplusplus
}
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
test.c的
#include "test.h"
#include <stdlib.h>
static handler_t handler_ = NULL;
void set_handler(handler_t h) {
handler_ = h;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar);
}
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
#include "test.h"
#include <iostream>
using namespace std;
class Foo {
public:
Foo() : ctr_(0) {};
// handler needs to …Run Code Online (Sandbox Code Playgroud) 如何将动态生成的C++函数作为*funcprt传递给C API?
API导出:
DllImport void api_register_func(char *func_name, void (*funcptr)(char *, char *));
Run Code Online (Sandbox Code Playgroud)
我必须在运行时创建函数,因为我之前不知道它.所以我用了一堂课:
class JsFunc
{
public:
char * JsFuncName;
char * JsParameter;
void RunFunc(char * val1, char * val2)
{
printf("\nJsFunc.runFunc executed, JsParameter=%s passed\n",JsParameter);
}
};
Run Code Online (Sandbox Code Playgroud)
并称之为:
JsFunc * jsm = new JsFunc ();
jsm->JsFuncName = external_parameter1;
jsm->JsParameter = external_parameter2;
api_register_func(external_parameter1, jsm->RunFunc);
Run Code Online (Sandbox Code Playgroud)
但VisualStudio 2015告诉我:
错误C3867'JsFunc :: runFunc':非标准语法; 使用'&'创建指向成员VJCS C的指针:\ Users\astrauss\Source\Repos\VCJS\VCJS\VCJS.cpp 54
对不起,如果代码不好,我不是C/C++程序员,但需要让我的日常工作运行.谢谢!
我有一个具有实例函数(或方法?)的类.在一个实例中,我尝试将指向这些函数的指针传递给库.该库需要静态函数.
当我将指针传递给回调函数时,编译器会抱怨我的函数不是静态的.我试图将它们设为静态,但如果我这样做,那么我就无法从函数中访问实例字段.
我怎么能绕过这个?
类似的问题是:使用C++类成员函数作为C回调函数,他们建议将方法设置为静态.但是我做不到,或者我不知道我怎么做.
GlutController::GlutController (int argc, char **argv) {
// stuff ..
// Register callbacks
glutSpecialFunc( OnSpecialKeys ); // Error, need static functions
glutReshapeFunc( OnChangeSize ); // Error...
glutDisplayFunc( OnRenderScene ); // Error...
// stuff ..
}
GlutController::~GlutController() {
}
void GlutController::OnChangeSize(int aNewWidth, int aNewHeight){
glViewport(0,0,aNewWidth, aNewHeight);
mViewFrustrum.SetPerspective( APP_CAMERA_FOV, // If this function is
float( aNewWidth ) / float( aNewHeight ), // static, this won't
APP_CAMERA_NEAR, // work
APP_CAMERA_FAR );
mProjectionMatrixStack.LoadMatrix( // Same here
mViewFrustrum.GetProjectionMatrix() ); …Run Code Online (Sandbox Code Playgroud) c++ glut member-function-pointers function-pointers freeglut
在我们打算用 C++ 编写的项目中,我们使用 C 库。该 C 库提供了注册回调的函数,这些函数在每次中断时调用。我们在构造函数中注册回调。所以我们基本上有以下(简化的)结构:
OurClass::OurClass() {
//the registerISRCallback is the C function, that accepts as first parameter the pin,
//the interrupt is expected on and as second parameter a function pointer:
//void (*callbackFunction)(int number, int time)
registerISRCallback(SCLK, handle_interrupt);
}
void OurClass::handle_interrupt(int pin, int time) {
//example: Blink a Led on the instance-LedPin
}
Run Code Online (Sandbox Code Playgroud)
然而问题是双重的:
void (OurClass::*)(int, int)。因此不可能这样使用它。有没有更多的解决方案可以在我们的类中使用这个 C API 函数并保持代码干净和可读?