实际的调用链:Node.js -> C++ addon -> mpv-1.dll
因此我们的目标是构建一个C语言扩展,其中调用mpv这个动态链接库的方法。前期折磨的地方在于编译,而不是具体的调用方法。 工具链和上文提到的相同,CMake.js + MSVC,在Windows上编译。
使用的CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
# Name of the project (will be the name of the plugin)
project(addon)
# Build a shared library named after the project from the files in `/`
file(GLOB SOURCE_FILES "*.c" "*.h" "include/*.h")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
# Gives our library file a .node extension without any "lib" prefix
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
# Essential include files to build a node addon,
# You should add this line in every CMake.js based project
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_JS_INC})
# Essential library files to link to a node addon
# You should add this line in every CMake.js based project
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
link_directories("${CMAKE_SOURCE_DIR}")
target_link_libraries(${PROJECT_NAME} "${CMAKE_SOURCE_DIR}/mpv.lib")
注意到第三行我们使用project(addon)
命令,因此这个项目就叫addon。变化的地方在于最后两行,指定了动态链接库的查找位置,并给“addon”这个目标链接“mpv.lib”这个库。生成的模块在/build目录下。
调用方法
如果使用bindings模块来加载我们写的C语言扩展,则查找的路径是在js所在目录下的/build文件夹内。因此调用扩展的js脚本应该与编译生成的/build目录同级,并且与实际引用的mpv-1.dll同级。
架构匹配问题
应该保证:链接库的目标架构 = 编译目标架构 = Node.js安装架构。
线程/生命周期问题
使用mpv_create
方法创建的mpv实例运行在另一个线程中。因此,只要保证NodeJS的主线程没被终止,播放将持续进行。
同时,C++ Addon的声明周期与主线程相同,因此使用全局变量可以保证不被释放。