为我的C++应用程序提供SDK
Providing SDK for my C++ Application
假设我正在C++中创建一个游戏引擎,我只想提供一些标题,而不是提供整个源代码,并且需要这些标题来创建新的游戏实例、提供Script类、提供游戏对象类和组件、数学等
是的,很明显我想为我的游戏引擎提供SDK,但如何做到这一点,如何只提供一些公共头文件并隐藏源文件和仅引擎头文件?如何将这些标头链接到源的其余部分?
我在Linux平台上使用Eclipse CDT。
通常,通过提供共享(动态)库并在头文件中提供纯虚拟接口,以及一些外部C入口点(为了实现跨编译器兼容性,因为每个编译器对C++名称的处理方式不同),可以获得最佳(容易)实现的二进制兼容性。
一个好的起点可以是这篇文章:http://chadaustin.me/cppinterface.html-它主要针对Windows,但也可以应用于Linux。
实际上,我在设计共享库(在Windows和Linux中都可以使用)时曾将其作为起点,但我放弃了自定义运算符delete,转而直接调用destroy方法(实际上是通过自定义的智能指针)。
在Linux下,还建议使用编译器的"visibility"标志,默认情况下将所有内容都隐藏("-fvisibility=hidden"),并且只将需要导出的函数标记为__attribute__ ((visibility ("default")))
(注意,您只需要导出外部"C"入口点,纯虚拟接口不需要导出)。
为了更好的二进制兼容性,您甚至需要避免虚拟方法,并实现自己的虚拟表(与用户可能使用的每个编译器兼容),但纯虚拟接口实际上已经足够兼容了。
对于静态库,您可能会遇到问题,因为您可能需要为用户可能使用的每个编译器(有时甚至是同一编译器的不同版本)提供一个静态库。
例如,界面可能看起来像:
class Interface {
public:
virtual void destroy() = 0;
protected:
// prevent to call delete directly
// - needs to be done in every public interface class
~Interface() {}
};
class IGameComponent: public Interface {
public:
virtual int32_t someMethod() const = 0;
protected:
~IGameComponent() {}
};
class IGameEngine: public Interface {
public:
// call component->destroy() when done with the component
virtual IGameComponent * createComponent() const = 0;
protected:
~IGameComponent() {}
};
extern "C"
__attribute__ ((visibility ("default")))
IGameEngine * createEngine();
然后实现可以看起来像:
// CRTP to avoid having to implement destroy() in every implementation
template< class INTERFACE_T >
class InterfaceImpl: public INTERFACE_T {
public:
virtual void destroy() { delete this; }
virtual ~InterfaceImpl() {}
};
class GameComponentImpl: public InterfaceImpl<IGameComponent> {
public:
virtual int32_t someMethod() const
{ return 5; }
};
class GameEngineImpl: public InterfaceImpl<IGameEngine> {
public:
virtual IGameComponent * createComponent() const
{
try {
return new GameComponentImpl;
} catch (...) {
// log error
return NULL;
}
}
};
extern "C"
IGameEngine * createEngine()
{
try {
return new GameEngineImpl;
} catch (...) {
// log error
return NULL;
}
}
这就是我实现库接口的原理。建议将分配的对象封装在智能ptr中,但要进行自定义,以便它调用Interface::destroy()而不是delete。
还要注意int32_t的使用——一般来说,如果你想让接口尽可能与跨编译器兼容,你应该使用固定大小的类型(例如size_t,这也适用于bool和enum,它们都高度依赖于编译器,但int、short、long等也是如此)。
进一步注意尝试/捕捉防护装置的使用,通常,如果您希望API可以从不同的编译器使用,则不应允许异常通过API边界(有时甚至在同一编译器的调试/非调试版本之间使用,但这更适用于Windows;但是,当库与太不同的版本(如GCC编译器)一起使用时,仍然可能会出现问题)。
这是一个您想要的视频->在eclipseCDT中创建一个静态库https://www.youtube.com/watch?v=kw3UD_YCoEk
您也可以创建一个动态库,但首先从静态库开始。
- 试图在visual studio上用C++创建一个桌面应用程序
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 在C应用程序中运行C++(带有STL)函数
- 使用VerQueryValue检索应用程序的文件描述
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用调试/崩溃报告将应用程序部署到客户端
- C++控制台应用程序阻止退出
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 将应用程序从32位移植到64位时出现问题
- 如何改变c++应用程序的视觉效果
- WM_CTLCOLORSTATIC从未在WIN32应用程序中触发
- 如何在Android上使用冰球应用程序SDK和Qt
- 使用AWS-SDK-C 构建MacOS C 命令行应用程序
- 使用 AMD APP SDK 2.9 创建符合 OpenCL 1.1 的应用程序
- 为我的C++应用程序提供SDK
- 安卓sdk组件:在新的sdk组件(应用程序)中添加对gnustl_static的支持
- 依赖于mac的sdk的Qt应用程序在otool列表中有@executable_path..我该怎么改
- 如何用kinect SDK应用程序制作GUI
- 语音识别SDK/API和Windows 8商店应用程序(c++)
- 我可以在Surface RT上运行Windows 2003 SDK应用程序吗