草庐IT

c++ - C/C++ API 谜题

coder 2024-02-04 原文

这是 an earlier question 的完全重写版本;我认为第一个版本省略了重要的细节;这一个提供了所有上下文。

我有一些 C++ API 的 header 。 API 声明了几个这样的类:

class Foo
{
public:
    inline void Bar(void);
    /* more inlines */
private:
    inline Foo();
    /* maybe more inline constructors */
}

即没有成员,所有函数都是内联和公共(public)的,构造函数除外。构造函数是私有(private)的,因此,据我了解 C++,我不能真正调用它们。要创建这些对象,我应该对它们使用 auto_ptr:

class FooAutoPtr : public std::auto_ptr<Foo> 
{
public:
    inline FooAutoPtr();
    /* one for each Foo constructors */
}

该 API 还有第二组函数,如下所示:

void Foo_Bar(void *self);
Foo* Foo_Constructor();

我们称它们为核心函数,因为这些是实际从主机应用导出的符号。不是 C++ 类。

核心函数具有 C 链接(即它们声明为 extern "C"),但它们被声明为采用和返回 C++ 类型(例如它们可以采用引用:Foo &foo)。最后,头文件包含 C++ 类的内联函数的实现。所有这些功能都做同样的事情:它们调用核心功能。例如,FooAutoPtr 构造函数是这样的:

inline FooAutoPtr::FooAutoPtr()
{
   reset(Foo_Constructor());
}

据我所知,代码从主机应用程序接收到一些应该是指向 Foo 的指针的对象,并将 auto_ptr gizmo 更改为指向该对象.但对于开发人员来说,它看起来好像是指向 Foo 的真正指针。调用 Foo::Bar() 是这样的:

inline Foo::Bar()
{
    Foo_Bar(this);
}

这适用于所有 C++ 类和方法。聪明吧?

现在,有人可以解释一下这一切是什么意思吗? :) 这不是真正的 C++ API,是吗?在我看来,它更像是 C API 之上的薄 C++ 包装器。如果是这样,我可以重新声明核心函数以丢失 C++ 位吗?我了解如何围绕 C++ 编写 C 包装器(实际上,我已经编写了它),但是,如果可能的话,我宁愿丢掉包装器并直接使用函数。但是我如何丢失 C++ 的东西呢?

例如,可能有一个带有引用的函数:

Bar& Foo_GetBar(void* self, const Baz& baz, int& i);

现在我从我的 C++ 包装器中这样调用它:

typedef struct bar bar_t; /* and others */
/*...*/
bar_t*
foo_get_bar(foo_t* foo, baz_t* baz, int* i)
{
    return (bar_t*) &Foo_GetBar(foo, *(Baz*)baz, *i);
}

它有效(我不知道如何)。但我宁愿像这样重新声明它:

/* type? */ Foo_GetBar(foo_t*, /* type? /*, /* type? */);

更新:我发现了一件有趣的事情,证实了 Neil's answer .使用相同 API 的是 Common Lisp 中的代码。 (当然,它必须使用 C 部分。)而且,根据我在源代码中(几乎)无法阅读的内容,作者只是使用指针代替了引用。以下是将 C++ 声明转换为 Lisp 的代码片段:

;; use * instead of & - we're not interested in C++ details
line (regex-replace-all "&" line "*")

就是这样 :) 谢谢大家!

最佳答案

理论上,编译器如何处理 C 链接声明中的引用的细节是未指定的实现细节。然而,许多编译器将其视为指针。因此,如果 C++ 库 header 导入 Bar& Foo_GetBar(void* self, const Baz& baz, int& i); 那么您可以尝试将其作为 bar_t* Foo_GetBar(foo_t* self) 导入到您的 C header 中, const baz_t* baz, int* i); 它可能会起作用。

关于c++ - C/C++ API 谜题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9010124/

有关c++ - C/C++ API 谜题的更多相关文章

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

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

  2. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  6. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  7. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby-on-rails - 是否使用 API - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我的公司有一个巨大的数据库,该数据库接收来自多个来源的(许多)事件,用于监控和报告目的。到目前为止,数据中的每个新仪表板或图形都是一个新的Rails应用程序,在巨大的数据库中有额外的表,并且可以完全访问数据库内容。最近,有一个想法让外部(不是我们公司,而是姊妹公司)客户访问我们的数据,并且决定我们应该公开一个只读的RESTfulAPI来查询我们的数据。我的观点是-我们是否也应该为我们的自己

  10. ruby - Ruby 中的必应搜索 API - 2

    我读了"BingSearchAPI-QuickStart"但我不知道如何在Ruby中发出这个http请求(Weary)如何在Ruby中翻译“Stream_context_create()”?这是什么意思?"BingSearchAPI-QuickStart"我想使用RubySDK,但我发现那些已被弃用前(Rbing)https://github.com/mikedemers/rbing您知道Bing搜索API的最新包装器(仅限Web的结果)吗? 最佳答案 好吧,经过一个小时的挫折,我想出了一个办法来做到这一点。这段代码很糟糕,因为它是

随机推荐