vs 运行库知识点

一、问题

  • 我们编译c/c++的执行程序(exe),如果运行库没有选择静态编译(mt),那么可能在别的电脑上就无法运行(因为没有对应的运行库)
  • 程序选择mt静态遍历,我们链接别的第三库会出现链接报错

上面是我们用c/c++编译经常遇到问题。

二、运行具体文件的作用[vs2019为例子]

  • vcruntime140: c语言运行库,比喻我们用到prinf
  • msvcp140.dll c++ 运行库 ,比喻我们用到的 std::cout
  • 其他补充,以前的版本不一定有,有可能是win10才有

140 代表是运行库的版本号,你用的vs版本不一样,这里数字不一样。

三、解释

1:问题1解决办法

  • exe 运行库选择mt,这个在vs 工程选项 c/c++ 运行库进行设置
  • 安装包写脚本自动检测,安装对应的运行库程序【用的不少,但国内版本比较多,不一定能安装成功】
  • 自己直接在exe运行库放 所有运行库,直接从vs 目录找到对应的版本运行库就可以了【这种比较多】

2:问题2解决办法

如果你exe选择静态遍历,第三方库选择md 动态编译,链接时候会发现运行库的代码已经实现,出现冲突,相当于定义出现2次了,导致无法链接。【凭记忆写的,改天自己用一个第三方库验证一下】

第三方库也选择静态编译就不会冲突了,但实际中非常麻烦,这个c/c++ 非常不方便地方,跟现在高级语言比起来麻烦很多,导致新手门槛太高。我自己都不怎么用c/c++写一些工具,用别的高级语言,直接几行命令就可以继承第三方的库直接开始工作,c/c++还需要单独编译,单独编译还不一定能成功。

四、总结

本篇文章只是为了记录一下,因为前段时间正好思考这个问题,到底他们运行库怎么搞的,为什么会编译出错等等。有些问题不思考,不验证还真不知道具体原因,只知道那样子操作就可以,但具体为什么却不知道

node js 调用dll 方案

最近准备用node js 写一个项目,所以需要对方案进行调研,项目会用到c的dll,通过网上查资料发现基本2种方案:1:ffi 2:addon

ffi 方案

这个方案我经过一天测试,发现这个方案不行,我建议直接放弃,第一个问题安装ffi 编译不通过,通过大量资料查询因为他不支持node 12 ,我通过使用别人ffi-napi 解决这个问题,然后遇到字符串问题,以前的接口默认是wchar_t * ,发现无论使用ref-wchar_t-napi 都无法使用宽直接,后面实在没有办法,我直接转换dll的接口改成utf-8进行传递,来解决字符串问题。最恐怖我发现ffi这个方案内存泄漏实在恐怖了,我防止是我自己API的问题,我直接调用系统的API,发现如果调用很频繁会导致内存泄漏,这点我完全无法接受,因为我的程序需要长期后台运行,那么内存问题是一个恐怖的问题

ffi测试代码

k = ffi.Library("Kernel32", {
  'OutputDebugStringA': ['void', ['string']],
});


var sleep = require('sleep');
for(var i = 0 ; i < 10000; i++){
  var r = k.OutputDebugStringA('' + i);
  r = null;
}

//等待100秒,观察内存是否释放,时间可以设置更长
sleep.sleep(100);

我自己观察内存一直私有内存一直增加,循环跑完也没有回收,那么说明ffi 有内存泄漏

addon

这个用起来挺简单,本质在windows就是一个DLL,通过工具生成一个动态库工程,然后直接按照例子写代码就可以了,也方便自己写代码,这里面有几种,我目前建议采用napi这种,这种就是没有v8版本,导致编译的问题,上面ffi编译的问题就是这个原因。

使用过程:

  • 百度一个addon教程
  • 找到nodejs 官方例子,直接按照例子写就可以 https://github.com/nodejs/node-addon-examples
  • 直接跑就可以(node32 才能加载win32 dll 不然会报错),上一个方案时候就出现加载问题,目前我用node32 12的版本

备注

nodejs 开发代码确实方便很多,但从一个技术方案迁移到另外一个技术方案,成本还真不少。ffi 内存泄漏,这个就不用考虑,ffi本质也是addon技术实现,这种中间件,但网上貌似都没有遇到这个问题一样,我直接测试好几个例子都会内存泄漏。ffi可以不用自己开发一个dll来做桥梁,addon需要自己单独写一个新的dll来调用原来的dll。