【问题标题】:How would I wrap a C API without exposing the C API?如何在不暴露 C API 的情况下包装 C API?
【发布时间】:2017-05-26 14:41:57
【问题描述】:

我想将一个 C API 封装到一组 C++ 类中,但同时最好让这些类的使用者对该 API 不了解。

例如包装Lua的C api尝试1:

// State.hpp
#pragma once
struct lua_State;
class State {
private:
    lua_State *state;
public: 
    State();
    ~State();
    void runFile(char* name);
};

那么对于cpp文件:

// State.cpp
#include "State.h"
#include "lua.hpp"
State::State() {
    state = luaL_newstate();
    luaL_openlibs(state);
}
State::~State() {
    lua_close(state);
}
void State::runFile(char* name) {
    luaL_dofile(state, name);
}

这意味着任何包含 State.hpp 的文件都会看到 lua_State,这是不可取的。我想要的是任何文件,包括 State.hpp not 看到 C API 的任何部分,包括它的结构,但我也不想使用 void* 或其他东西并在每个文件中强制转换为 lua_State成员函数。我看到 opaque pointers 是一种方法来做我想做的事,但我没有看到将私有结构定义为 lua_State 的方法。

【问题讨论】:

  • 你接受pimpl idiom?
  • 如果您想避免 pimpl,请尝试使用 namespace detail 或任何其他明显意味着不要触摸的命名空间名称
  • Pimpl:希望避免使用m.state 或类似方法来访问成员函数中的状态。命名空间:你的意思是在包装特定的命名空间或其他东西中转发声明 lua_State 结构?
  • 第一个 sn-p 一个不透明的指针。任何消费者只会知道有一个名为lua_Statestruct,但对结构内部的内容一无所知。如果这还不够好,确实,去买个粉刺吧。
  • 哦,好的。那时可能会和 pimpl 一起去。谢谢。

标签: c++ c


【解决方案1】:

最简单的转发方式是转发声明项目。

  struct lua_state;

这让用户可以看到使用了一个叫做 lua_state 的东西,但看不到细节。

粉刺

向前声明一个结构

struct hiddenData;

在你的课堂上使用这个结构

class State {
private:
    hiddenData *state;
public: 
    State();
    ~State();
    void runFile(char* name);
};

在 cpp 文件中。

// State.cpp

#include "State.h"
#include "lua.hpp"

struct hiddenData {
    lua_state * L;
    // for ease of use...
    hiddenData( lua_state * l ) : L(l) {}
}
State::State() {
    state = new hiddenData( luaL_newstate() );
    luaL_openlibs(state->L);
}
State::~State() {
    lua_close(state->L);
}
void State::runFile(char* name) {
    luaL_dofile(state->L, name);
}

【讨论】:

    猜你喜欢
    • 2019-07-13
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2010-09-14
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多