草庐IT

作为 C 回调的 C++ 静态成员函数需要访问非静态引用

coder 2024-02-25 原文

在我的 C++ 代码中,我依赖于 C 库。这个 C 库让我可以定义一个带有 3 个参数的回调。示例:

文件.c:

#ifdef __cplusplus
extern "C"{
#endif
     typedef void(*callback)(argument* 1, argument* 2, argument* 3);
...
     void set_callback(ARG1, callback name_of_callback);
...

在我正在开发的 C++ 库中,我希望这个回调成为一个类的成员函数,因为我不能直接将成员函数作为回调传递给 C 库,我创建了一个静态函数作为回调并在内部这个静态函数我想引用一个类对象并调用它的成员函数来完成工作。

现在我的问题是我的静态函数需要有 C 库指定的 3 个参数,所以我找不到一种方法来引用我在该静态函数中开发的类的对象。我想做的例子:

我的类.h:

class MyClass:
public:
   MyClass();
   void my_function(argument*1, argument* 2, argument* 3);
   static void my_callback(argument* 1, argument* 2, argument*3);

我的类.cpp:

MyClass::MyClass(){
    set_callback(ARG1, my_callback);
}

void MyClass::my_function(argument*1, argument* 2, argument* 3){ 
      /* Do something */}
void MyClass::my_callback(argument* 1, argument* 2, argument*3){
    Object->my_function(1, 2, 3);
}

不将类成员设置为静态的原因是我希望能够出于测试目的创建和销毁此类的对象并控制测试中对象的状态。

我正在使用 g++ 和 gcc,希望有人能对此提供一些帮助。 提前致谢。

最佳答案

您可以创建静态成员函数或纯“C”函数来执行此操作,请考虑下面的示例:

/**
 * C++ part
 */
class obj
{
public:
    obj() {}
    ~obj() {}

    void doSomething(int a, int b) { cout << "result = " << a+b << endl; }
};

/**
 * C Part
 */
#ifdef __cplusplus
extern "C"
#endif
{
typedef void (*callback)(void* one, void* two, void* three);

callback g_ptr = NULL;
void* arg = NULL;

void c_lib_core (void)
{
    printf ("C Lib core...\n");
    if (g_ptr)
    {
        g_ptr(arg, NULL, NULL);
    }
}

void set_callback (void* arg, callback ptr)
{
    g_ptr = ptr;
}

void my_callback (void* one, void* two, void* three)
{
    obj* my_obj = (obj*) one;

    my_obj->doSomething(1,2);
}

#ifdef __cplusplus
}
#endif



int main (void)
{
    obj a;

    set_callback (&a, my_callback);

    c_lib_core ();
}

输出:

C Lib core...
result = 3

我将一个指向 C++ 对象的指针作为参数 1 传递。这允许回调将其转换回 C++ 并调用它。 c_lib_core 的东西只是为了测试目的模拟回调函数的回调。这与全局变量一起将位于 C 代码中的某处。您只需实现一个 C 函数并将 ARG1 设置为您的对象即可。

关于作为 C 回调的 C++ 静态成员函数需要访问非静态引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23048683/

有关作为 C 回调的 C++ 静态成员函数需要访问非静态引用的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  6. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  7. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  8. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  9. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  10. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

随机推荐