如何在不公开 C API 的情况下包装 C API

How would I wrap a C API without exposing the C API?

本文关键字:API 情况下 包装      更新时间:2023-10-16

我想将 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 在内的任何文件都看不到 C API 的任何部分,包括其结构,但我也不想在每个成员函数中使用 void* 或其他东西并强制转换为lua_State。我看到不透明的指针是做我想做的事的一种方法,但我看不到定义要lua_State私有结构的方法。

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

  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);
}
相关文章: