实际的调用链: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的声明周期与主线程相同,因此使用全局变量可以保证不被释放。