背景:有一个用了boost库的c++项目(编译、运行无报错的demo),把这个demo整合到nodejs c++插件里遇到了各种编译问题。
实际上要做的就是把在vs里设置的东西,用gyp设置一次。
报错 error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MT_StaticRelease”
运行库( c/c++-代码生成-运行库)设置不对
binding.gyp
'configurations': {
'Debug': {
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': '3', # /MDd
},
},
},
'Release': {
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': '2', # /MD
},
},
},
},
报错 LINK : fatal error LNK1194: 无法延迟加载“node.exe”
报错 LINK : fatal error LNK1194: 无法延迟加载“node.exe”,原因在于数据符号“"__declspec(dllimport) const std::basic_ostream<char,struct std::char_traits<char> >::`vftable'" (__imp_??_7?$basic_ostream@DU?$char_traits@D@std@@@std@@6B@)”的导入;链接时不使用 /
DELAYLOAD:node.exe
binding.gyp
'win_delay_load_hook': 'false',
报错 error LNK2038: 检测到“boost__type_index__abi”的不匹配项: 值“RTTI is used”不匹配值“RTTI is off - typeid() is used only for templates”
binding.gyp
'configurations': {
'Debug': {
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeTypeInfo': 'true', # 开启RTTI
},
},
},
'Release': {
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeTypeInfo': 'true', # 开启RTTI
},
},
},
},
报错 error LNK2001: 无法解析的外部符号 "void __cdecl boost::throw_exception(class stdext::exception const &)"
参考 BOOST应用 无法解析的外部符号 "void __cdecl boost::throw_exception(class std::exception const &)"
binding.gyp
'configurations': {
'Debug': {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': ['/EHsc'] # 启用c++异常
},
},
},
'Release': {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': ['/EHsc'] # 启用c++异常
},
},
},
},
报错 error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl std::bad_cast::bad_cast(class std::bad_cast const &)"
逐段代码注释,最后定位到get_random_bytes有问题,最后发现是boost::numeric_cast<boost::winapi::ULONG_>(siz),这里强转有问题,换成static_cast强转就好了
random_provider_bcrypt.ipp
void get_random_bytes(void *buf, std::size_t siz)
{
boost::winapi::NTSTATUS_ status =
boost::winapi::BCryptGenRandom(
hProv_,
static_cast<boost::winapi::PUCHAR_>(buf),
/*boost::numeric_cast<boost::winapi::ULONG_>(siz),*/
static_cast<boost::winapi::ULONG_>(siz),
0);
if (BOOST_UNLIKELY(status != 0))
{
BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptGenRandom"));
}
}