如何解决为 NodeJS 运行我的 C++ 插件时,PortMidi Pm_OpenInput() 函数崩溃
我正在尝试使用 Electron 和 C++ 插件 制作一个简单的 DAW,并且我想使用 PortMidi 来支持 Midi 键盘。
我制作了一个 midi.h
脚本来查看 PortMidi 是否有效,并且我设法使用 mingw-g++ 编译和运行该脚本(并且它有效),但是当我使用 node-gyp 构建 nodejs 插件,并运行应用程序,它在执行 Pm_OpenInput(&midi_in,id,NULL,NULL);
期间显示此错误(我认为这意味着 C++ 脚本无缘无故停止了......)
npm ERR! code ELIFECYCLE
npm ERR! errno 4294930435
npm ERR! fynewav@0.1.0 start: `electron ./server/main.js`
npm ERR! Exit status 4294930435
npm ERR!
npm ERR! Failed at the fynewav@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
我在 .lib
子文件夹中使用此命令从这个 github 存储库 https://github.com/philandstuff/portmidi 为 PortMidi 自己生成了 .dll
和 /build/
文件:
cmake .. -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL -DBUILD_SHARED_LIBS:BOOL=ON -DPM_CHECK_ERRORS=ON; cmake --build .
这是我的 midi.h
文件:
#include <iostream>
#include <thread>
#include "portmidi.h"
#define MIDI_SYSEX 0xf0
#define MIDI_EOX 0xf7
int active = FALSE;
bool running = true;
std::thread midiThread;
PmStream *midi_in;
int thru_sysex_in_progress = FALSE;
int app_sysex_in_progress = FALSE;
void process_midi()
{
while (running)
{
PmError result;
PmEvent buffer;
if (!active) continue;
if (!app_sysex_in_progress) {
do {
result = Pm_Poll(midi_in);
if (result) {
int status;
int rslt = Pm_Read(midi_in,&buffer,1);
if (rslt == pmBufferOverflow)
continue;
status = Pm_MessageStatus(buffer.message);
if (((status & 0x80) == 0) && !thru_sysex_in_progress) {
continue; /* sysex old data,ignore */
}
int i = Pm_MessageData1(buffer.message);
int i2 = Pm_MessageData2(buffer.message);
int s = Pm_MessageStatus(buffer.message);
printf("Note %d - Force %d - State %s\n",i,i2,(s==128)? "Off": "On");
/* sysex processing */
if (status == MIDI_SYSEX) thru_sysex_in_progress = TRUE;
else if ((status & 0xF8) != 0xF8) {
/* not MIDI_SYSEX and not real-time,so */
thru_sysex_in_progress = FALSE;
}
if (thru_sysex_in_progress && /* look for EOX */
(((buffer.message & 0xFF) == MIDI_EOX) ||
(((buffer.message >> 8) & 0xFF) == MIDI_EOX) ||
(((buffer.message >> 16) & 0xFF) == MIDI_EOX) ||
(((buffer.message >> 24) & 0xFF) == MIDI_EOX))) {
thru_sysex_in_progress = FALSE;
}
if (thru_sysex_in_progress)
std::cout << "sysex in progress" << std::endl;
}
} while (result);
}
}
}
void portopen()
{
const PmDeviceInfo *info;
Pmdeviceid id;
PmError err = Pm_Initialize();
midiThread = std::thread(process_midi);
id = Pm_GetDefaultInputdeviceid();
info = Pm_GetDeviceInfo(id);
if (info == nullptr)
{
std::cout << "No Midi device found" << std::endl;
return;
}
printf("opening input device %s %s\n",info->interf,info->name);
Pm_OpenInput(&midi_in,NULL);
Pm_SetFilter(midi_in,PM_FILT_ACTIVE | PM_FILT_CLOCK);
active = true;
return;
}
void portClose()
{
active = false;
running = false;
midiThread.join();
Pm_Close(midi_in);
Pm_Terminate();
}
这是我用 mingw-g++ 编译的 main.cpp
文件来尝试 PortMidi(它适用于 g++)
#include "midi.h"
int main(int argc,char const *argv[])
{
portopen();
std::this_thread::sleep_for(std::chrono::seconds(5));
portClose();
}
这是我用于 node-gyp 的 binding.gyp
文件:(我只为 Windows 制作了正确的包含)
{
"targets": [
{
"target_name": "engine","sources": [ "./engine/wrapper.cpp" ],"include_dirs": [
"<(module_root_dir)/engine/include/","<!@(node -p \"require('node-addon-api').include\")"
],'conditions': [
['OS=="win"',{
'defines': [
'__WINDOWS_MM__'
],'link_settings': {
'libraries': [
"-lOpenAL32","-lsndfile","-lportmidi"
],'library_dirs': [
"<(module_root_dir)/engine/lib/"
]
}
}
],['OS=="linux"',{
'cflags_cc!': [
'-fno-exceptions'
],'defines': [
'__LINUX_ALSASEQ__'
],'link_settings': {
'libraries': [
'-lal'
]
}
}
],['OS=="mac"',{
'defines': [
'__MACOSX_CORE__'
],'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
},'link_settings': {
'libraries': [
'OpenAL.framework',],}
}
]
]
}
]
}
我已经尝试执行 node-gyp clean
、.\node_modules\.bin\electron-rebuild
、node-gyp configure
、node-gyp build
并为 .lib 和 .dll
文件>OpenAL、sdnFile 和 PortMidi。
我还尝试使用 Pt_Start()
和 Pt_Stop()
而不是为 process_midi
函数创建我自己的线程,但它没有改变任何东西。
我检查了 portmidi.c
源文件,似乎第 733 行导致了问题,但我有点迷茫......
/* open system dependent input device */
err = (*midi->dictionary->open)(midi,inputDriverInfo);
我使用的是 Windows 10 专业版:
- node-gyp v8.1.0
- 电子 v13.1.2
- 节点 v14.16.0
c++ 插件与 sndFile 和 OpenAL 一起工作正常,但只有 PortMidi 不起作用:/
可在此处找到该应用的所有源代码:https://github.com/FurWaz/FyneWav
如果有人能给我提示或建议其他用于 MIDI 的 C++ 库,那将非常有帮助 ^^ 谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。