插件允许您扩展 Solar2D 的功能。本指南概述了基本细节。
Solar2D 在 plugins.solar2d.com 运行 Solar2D 免费插件目录。如果您创建了一个插件,请将其提交到 Solar2D 免费插件目录。您可以提交一个可以获取您插件的链接,或者免费分发它。或者,您可以将其提交到 Solar2D 插件市场,请参阅 资源打包指南。
Solar2D 插件利用 Lua 的模块系统,其中插件通过调用 Lua require() 函数进行延迟加载。
通常,这些插件只是共享的原生库,在以下平台上受支持:.dylib
).dll
).so
)
.a
)。.jar
) 通常很方便。在这两种情况下,Solar2D 添加了特殊的加载器,确保在遵循某些约定情况下可以轻松加载这些插件。
Solar2D 的插件托管在多个地方。许多插件可在 免费插件目录、Solar2D 市场 和 Solar2D 插件市场 中找到。您可以通过在 build.settings
的 plugins
表中添加一个条目来合并插件,例如
settings = { plugins = { ["plugin.myPlugin"] = { publisherId = "com.domainname" }, }, }
每个插件宿主将为单个插件提供特定的 build.settings。
以这种方式添加时,Solar2D 将在构建阶段集成插件。
然后,可以使用标准 Lua require() 函数加载插件,例如
local myPlugin = require( "plugin.myPlugin" )
可以轻松地将原生插件添加到您的 iOS 或 Android 项目中。
在 iOS 上,插件将采用静态库 (.a
) 文件的形式,需要将其链接到您的应用程序可执行文件中。
在 Android 上,插件可以采用 .so
(共享库)、.jar
或 .aar
文件的形式。
当您通过 Solar2D Native 添加插件时,请注意以下事项
如果您想 创建/提交 一个插件以在 Solar2D 插件市场 中可用,您可以使用我们的 App
项目模板来简化插件的开发和测试。毕竟,插件本身不是可执行文件,它必须在实际应用程序中运行。项目模板位于 Solar2D Native 文件夹中
/Applications/Corona/Native/Project Template/App/
此文件夹有单独的
ios
android
还有一个与这些文件夹并排放置的 Corona
文件夹,其中包含一个经典的 Corona 项目 (main.lua
)。您可以修改这些文件以测试您的插件提供的 Lua API。
在 ios
文件夹中,有两个 Xcode 项目
App.xcodeproj
— 这是构建在设备上运行的 .app
可执行文件的项目。它会自动将插件构建为隐式依赖项。
Plugin.xcodeproj
— 对于插件开发,您应该修改此项目。它将插件构建为静态库 (.a
),如果您想在 App
项目之外共享您的插件,则可以直接使用此项目。
大多数情况下,您需要为您的插件创建一个通用二进制文件。换句话说,您希望发布一个同时支持设备和
的静态库。您可以通过 lipo
工具完成此操作。在以下示例中,我们正在为 staticlibrary.a
创建一个通用库
lipo -create "/path/to/iphoneos/staticlibrary.a" "/path/to/iphoneos-simulator/staticlibrary.a" -output "/path/to/dst/staticlibrary.a"
在 android
文件夹中,内容包括
app
— 此模块构建安装在设备上的 .apk
。根据 app
模块的 build.gradle
脚本中 dependencies
块中的此条目 (compile project(':plugin')
),app
模块自动将插件构建为显式依赖项。
plugin
— 此模块将插件构建为 .jar
文件,仅包含项目中 plugin/src/main/java
下的 Java 文件。如果您想在 App
项目之外共享您的插件,则可以直接使用此项目。
插件构建在 Lua 的模块系统之上,因此它们可以有三种不同的风格
可以使用 CoronaLibrary 类创建 Lua 库插件。请参阅 创建 Lua 插件 指南,了解如何创建、打包并将 Lua 插件提交到可用市场的详细信息。
除了上面讨论的插件命名约定之外,Solar2D 还希望插件遵循一些额外的约定,以确保 Lua 可以找到这些模块。在 C 中,这些约定只是模块的标准 Lua 命名约定
luaopen_
为前缀。.
),则在函数名称中将其替换为下划线 (_
),因为 C 不允许符号名称中包含点。例如,Lua 库 plugin.myLibrary
将有一个名为 luaopen_plugin_myLibrary
的 Lua 函数
static int doSomething( lua_State *L ) { lua_getglobal( L, "print" ); lua_pushstring( "I did something!" ); CoronaLuaDoCall( L, 1, 0 ); return 0; } // Export so it's visible to "require()" CORONA_EXPORT int luaopen_plugin_myLibrary( lua_State *L ) { static const luaL_Reg kFunctions[] = { { "doSomething", doSomething }, { NULL, NULL } }; // Create "myLibrary" // Lua version assumes version and revision default to 1 int result = CoronaLibraryNew( L, "myLibrary", "com.mycompany", 1, 1, kFunctions, NULL ); return result; }
如果您使用 Java 编写模块,Corona 已将 Lua 设置为加载 Java 代码,并让该 Java 代码通过 JNLua 定义 Lua 库。在这里,Lua 查找 Java 类 LuaLoader
并对其进行实例化。
Solar2D 假设以下约定
LuaLoader
类有一个默认(空)构造函数。LuaLoader
类必须实现 JNLua 接口 com.naef.jnlua.JavaFunction
。LuaLoader
的命名空间应与传递给 require()
的名称相同。例如,Lua 库 plugin.myLibrary
将由plugin.myLibrary.LuaLoader
实现,并且该类将实现 com.naef.jnlua.JavaFunction
接口的 invoke()
方法。
您还可以以混合方式创建插件。例如,您可以通过 Lua 代码创建库,然后在原生 C 端进行进一步的初始化。
下面是使用 Lua 创建 myLibrary
库,然后在本机 C 端添加其他函数的示例。这里,我们假设 kBuffer
存储了对应于 myLibrary.lua
的 Lua 字节码。
// The bytecodes for "myLibrary.lua" are contained in kBuffer static const unsigned char kBuffer[] = { ... } static int bufferLoader( lua_State *L ) { return luaL_loadbuffer( L, (const char*)kBuffer, sizeof( kBuffer ), "myLibrary" ); } static int somethingElse( lua_State *L ) { printf( "I'm doing something else!" ); return 0; } CORONA_EXPORT int luaopen_myLibrary( lua_State *L ) { lua_CFunction factory = Corona::Lua::Open< bufferLoader >; int result = CoronaLibraryNewWithFactory( L, factory, NULL, NULL ); if ( result ) { const luaL_Reg kFunctions[] = { { "somethingElse", somethingElse }, { NULL, NULL } }; luaL_register( L, NULL, kFunctions ); } return result; }