适当的方式来暴露一个API在C++中:

huangapple go评论57阅读模式
英文:

Proper way to expose an API c++

问题

我正在为我的项目开发一个API,并希望将来在其他项目中使用这个API。问题是如何暴露它:

API使用了许多库,我不希望客户端代码一次又一次地下载和编译这些库。所以我的解决方案是像这样做:

Engine.hpp

class __declspec(dllexport) Engine
{
public:
    Engine();

    ~Engine();
public:
    void run_window();

    // std::vector<UI::Window*> window_list;
};

std::string __declspec(dllexport) get_version();

目前,它可以正常工作,但我想将一些其他我创建的类添加到这个公开的类中,但当我尝试包含我的类时出现问题,这个类依赖于一个类(在这种情况下是GLFW)。该类看起来像这样:

Window.hpp

#include <GLFW/glfw3.h>

class Window{
public:
   Window(std::string name);
   ...
private:
   GLFWwindow* m_window;
};

因此,尝试使用UI::Window自然会导致一个预编译错误,说它找不到GLFW头文件,这在客户端代码的CMake中没有包含。据我所知,Engine中的库函数应该与我的代码一起编译,并包含在.dll和.lib文件中,但我得到了这个预编译错误,这是预料中的。

我对API设计有点新,所以是否有一种方式/最佳实践可以将依赖于库的代码暴露给客户端,而不让他们导入每个库?

我可以在Engine的cpp文件中使用静态变量,但我希望这些变量成为类成员,并且我希望客户端能够访问其中的一些变量。

英文:

I'm developing an API for my project and I would like to use this API on future projects. The problem is how I expose it:

The API uses a lot of libraries and I don't want the client code to download and compile these libraries over and over again. So my solution is to do something like this:

Engine.hpp

class __declspec(dllexport) Engine
	{
	public:
		Engine();

		~Engine();
	public:
		void run_window();

		// std::vector&lt;UI::Window*&gt; window_list;
	};

	std::string __declspec(dllexport) get_version();

Right now this work as it is, but I want to add some other classes I've created to this exposed class, but the problem arises when I try to include my class, which is dependent on a class (in this case, GLFW). The class simply looks like this:

Window.hpp

#include &lt;GLFW/glfw3.h&gt;

class Window{
public:
   Window(std::string name);
   ...
private:
   GLFWwindow* m_window;
};

So attempting to use UI::Window naturally causes a pre-compilation error saying it can't find GLFW header files, which is not included in client code's cmake. As far as I'm concerned the functions of libraries in Engine should be compiled alongside my code and should be included in the .dll and .lib files, but I'm getting this include error as expected.

I'm a bit new to API design so is there a way / best practice to expose my library dependent code to the client without having them import every single library?

I can use static variables inside the cpp files of Engine but I want the variables to be class members and I want the client to access some of them.

答案1

得分: 2

You're #includeing Window.hpp in your compilation unit, and Window.hpp contains #include &lt;GLFW/glfw3.h&gt;, so that's what the compiler tries to do. It has no idea why you're including glfw3.h, just that you told it to do so and that it can't find that file.

Luckily, you don't actually need glfw3.h. Since Window only contains a pointer to a GLFWwindow it has no need for the full definition of GLFWwindow in its header; it just needs to know that it's a class that exists. You tell it that using a forward-declaration:

class GLFWwindow;

class Window{
public:
   Window(std::string name);
   ...
private:
   GLFWwindow* m_window;
};

Then in Window.cpp you can #include the full glfw3.h header so that the Window member functions defined there know what to do. That's fine though, since Window.cpp doesn't need to be compiled when compiling your program (only when compiling your library).

You will still need to link your program to the glfw libraries though.

英文:

You're #includeing Window.hpp in your compilation unit, and Window.hpp contains #include &lt;GLFW/glfw3.h&gt;, so that's what the compiler tries to do. It has no idea why you're including glfw3.h, just that you told it to do so and that it can't find that file.

Luckily, you don't actually need glfw3.h. Since Window only contains a pointer to a GLFWwindow it has no need for the full definition of GLFWwindow in its header; it just needs to know that it's a class that exists. You tell it that using a forward-declaration:

class GLFWwindow;

class Window{
public:
   Window(std::string name);
   ...
private:
   GLFWwindow* m_window;
};

Then in Window.cpp you can #include the full glfw3.h header so that the Window member functions defined there know what to do. That's fine though, since Window.cpp doesn't need to be compiled when compiling your program (only when compiling your library).

You will still need to link your program to the glfw libraries though.

huangapple
  • 本文由 发表于 2023年6月26日 19:25:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556228.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定