分类目录归档:笔记

[WebAssembly]初学笔记 从Javascript调用C++函数

如果有看不明白的地方请先看前置说明文章

要在js中使用c++编写的函数或者在c++中运行js代码,则需要有一些方法打通这两个环境,官方已经写了一个列表列举出了所有的方法,可以参考:https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html

在此我会对部分方法简单进行举例。

上一篇笔记说到如果不需要自动执行main,可以不写main函数,此时我们需要使用wasm中编写的函数就需要手动设置需要导出的函数。


函数导出

要从C++中导出函数给js环境使用,有两种方法:一种不用改动代码,需要在编译参数上进行指定,另一种需要在代码中添加宏来指定。

这两种方法的使用场景我认为是这样:如果有一份源码不是你写的,或者说就是引用别处的一个库,那么我们去修改其源码肯定不便于后期维护,因此在编译参数中指定导出的方法最稳妥,但如果要编译的源码就是你专门为了这个wasm项目写的,那么使用宏指定可以让编译参数更加简洁,在代码中也可以更清晰地看出导出了哪些函数。

方法一:需要在编译时添加参数指明要导出的函数名称:

-sEXPORTED_FUNCTIONS=_func1,_func2,_func3,其中func1,func2,func3是在c++中你定义的函数名称,作为导出函数时,需要在其名称前面添加一个下划线,然后这些函数就会被添加给wasm的实例对象。

现在将test.cpp的内容修改为下:

#include <iostream>
extern "C" { // 由于C++导出方法会对方法进行重命名,这是用来指定以C形式导出方法

//定义一个无返回值函数,参数为一个int
void poi1(const int val) {
	std::cout << "poi1: " << val << std::endl;//输出val的值
}
//定义一个返回整数的函数,参数为两个int
int poi2(const int val, const int val2) {
	std::cout << "poi2: " << val << " " << val2 << std::endl;//输出两个val的值
	return 114514;
}
//定义一个无返回值函数,参数为一个bool
void boolTest(bool val) {
	std::cout << "bool: " << val << std::endl;
}

}

然后执行命令编译:emcc -sMODULARIZE=1 -sASSERTIONS -sEXPORTED_FUNCTIONS=_poi1,_poi2,_boolTest -o dist/test.mjs test.cpp

继续阅读[WebAssembly]初学笔记 从Javascript调用C++函数

[WebAssembly]初学笔记 安装环境和尝试编译

以前也尝试过学WASM,但由于当时没有应用场景所以安装完环境就弃坑了,这次来好好学习一下用法。这篇笔记是边学边写的,如果有错误或者需要补充的地方请留言。

WASM通常需要使用其他高级语言编写后编译为wasm二进制文件交给运行时去运行,但如果你的头够铁,也可以尝试手写wasm指令,或者通过wasm的文本格式理解它的底层运行原理。

本笔记在Windows平台上使用C++编写源码编译为wasm,所以需要安装emscripten工具包。除了C++以外,Rust也是一个推荐选项,而其它语言目前还没有非常完备的支持。

安装Emscripten

这是用于把C/C++编译到wasm的工具包。

Emscripten的项目地址在:https://github.com/emscripten-core/emscripten

文档地址在:https://emscripten.org/index.html

安装方式官方手册在:https://emscripten.org/docs/getting_started/downloads.html,这里我简单介绍一下,但还以官方手册为准,我不会同步更新。

首先把emscripten仓库克隆到任意位置,然后进入该目录

git clone --depth 1 https://github.com/emscripten-core/emsdk.git

cd emsdk

然后依次执行以下命令进行安装

emsdk.bat install latest
emsdk.bat activate latest --permanent

上面的` –permanent`参数是为了让emsdk的命令在全局可用,否则你需要在每个命令环境中都执行一次activate。执行完了之后可以关闭当前的命令窗口,然后找个地方开始准备写我们的代码了。 继续阅读[WebAssembly]初学笔记 安装环境和尝试编译

[MySQL]JSON数组取对称差集函数

写了个函数,做个记录。作用是扣掉两个数组相同的部分,只保留不同的部分,也就是对称差集。

CREATE FUNCTION `array_diff`(`arr1` json, `arr2` json) RETURNS json
    NO SQL
    DETERMINISTIC
BEGIN
	RETURN (
		WITH 
		A AS (SELECT el FROM JSON_TABLE(arr1, '$[*]' COLUMNS(el INT PATH '$')) T),
		B AS (SELECT el FROM JSON_TABLE(arr2, '$[*]' COLUMNS(el INT PATH '$')) T)
		SELECT JSON_ARRAYAGG(el) FROM (
			SELECT el FROM A WHERE A.el NOT IN (SELECT el FROM B)
			UNION
			SELECT el FROM B WHERE B.el NOT IN (SELECT el FROM A)
		) AS T
	);
END

调用

select array_diff('[1,2,3]','[2,3,4]')

结果

[1, 4]

 

[git]fatal: detected dubious ownership in repository at

这是一篇笔记,因为是第二次碰到了,记录一下,下次好找。

Git的新安全策略会导致使用git操作无所有权的仓库目录时报此错误,要解决可以有以下方案:

  1. 把目录的权限修改正确,就不会有这个提示了。
  2. 把目录添加到信任列表
    • git config --global --add safe.directory "目录路径"
  3. 如果不想那么麻烦对所有出问题的目录进行这样的操作的话可以直接信任所有路径。目前还没研究该安全策略是为了避免什么问题,不知道这样做是否会造成什么不良后果。
    • git config --global --add safe.directory "*"

[node.js]在redis上使用数据搜索

reids本身是一个基于键值对数据存储的内存数据库,也就是只能通过数据的key来获取数据项目,那么它自然也就没有任何数据搜索方面的功能,只能依靠一定规则生成的key来获取数据。

虽然它的本体是这样,但redis也提供了几个模块为其添加了一部分搜索功能的支持,并将这些模块整合为了redis-stack,官网介绍:https://redis.io/docs/stack/,我暂时还没测试它是否可以直接替代原本的redis实例,但就命令形式上来看,应该是兼容的。

本文是对于redis-stack官网上提供的node.js示例记录的笔记。

安装

redis-stack的安装我就不介绍了,直接从官网下载就好,或者使用docker之类的,本文只记录如何使用。

要在node.js中使用redis-stack的相关特性,我们需要`redis-om`模块,使用`npm i redis-om`安装进需要它的项目,关于该模块更详细的API介绍可以去其npm包页面上或者github仓库查看:https://github.com/redis/redis-om-node,不过要注意的是官方的示例中有些地方是错的,我会在下面对应的部分说明。 继续阅读[node.js]在redis上使用数据搜索

[SASS]指定import查找路径

本文为node包sass的使用笔记。

写这篇文章,是因为我碰到了引用`node_modules`目录中模块的`scss`文件的需求,但是它总是提示找不到: “Error: Can’t find stylesheet to import.”,于是我搜了搜,发现说是要在渲染参数中添加`loadPaths`数组来告诉sass去哪里找依赖文件,我在这个模块的typescript类型定义中也找到了这个参数名,但是我加上了之后并没有用,于是研究一番发现这个包使用的实际上并不是`loadPaths`,而是`includePaths`这个参数名,所以觉得有必要写篇笔记记录一下。

另外我发现有的解决方案中说可以在import的url前面加个`~`来表示这个文件在`node_modules`里,但我试了也没有用,这个特性似乎是webpack给sass引入的importer,所以单独使用sass的render api时此方式是不起作用的,如果使用的是`sass-loader`的话可以使用这个方法。

[Excel]根据身份证号码计算年龄

最近被迫大量使用excel,所以我也学了点它的函数用法,做点笔记

根据身份证号码计算年龄的使用场景应该挺多的,但我在网上始终没找到一个能得到最准确结果的答案,于是东拼西凑写了个

#以下公式需要把#以及后面的内容删除才可以使用,因为excel的公式并不存在注释语法
=FLOOR(		#把计算结果向下舍入,精度为1
	DATEDIF(	#计算日期差
		TEXT(	#把生日字符串格式化为日期
			MID("身份证号",7,8),#提取身份证的生日部分
			"0-00-00"
		),
		TODAY(),#获取今天的日期
		"M"	#以月为单位计算前两个参数的差值
	)/12,		#除以12变成年
1)

网上很多方法是直接计算两个日期之间的年差,没有考虑到过了生日才长一岁的问题,所以我计算的是月差,毕竟每年的月份是固定12个,那么只要用总月数除以12再舍掉小数就是正确的周岁结果了

[Node.js]ES模块和CommonJS模块的导入

在使用ES导入语法的文件中想要使用require导入一个CommonJS模块的话,可以使用module.createRequire来创建一个require函数。

import { createRequire } from 'module';
const require = createRequire(import.meta.url);

 

在一般的使用CommonJS导入语法的文件中想要使用ES语法导入模块的话,可以使用`import`函数,要注意的是这是一个异步函数,返回一个`Promise`,所以需要`await`它或者使用`then`来等待返回结果,如下

(async()=>{
	const fs=await import('fs);
})();

 

[Browserify]异步插件导致write after end错误

写了个Browserify插件,之前一直没问题,但今天我改了点打包流程,结果一直报`write after end`错误,找了半个晚上,发现是因为我的插件函数写的是异步的,里面有个await异步读文件。

之前一直没出问题是因为后面的打包流程时间够长,能让这个插件正常执行完,但今天改了流程之后部分情况下很快就执行完了,于是当插件异步流程执行完后继续就出错了,修正方法是把异步文件读取改成同步的。

[Node.js]进程异常退出,错误码 3221226505

不是我想水一篇博文,在解决完前一篇博文的问题之后,立刻就又碰上另一个奇葩问题,进程直接跑着跑着没了,留下一个错误码3221226505。

在我左思右想把代码改来改去,包换来换去之后依然不能解决问题,然后发现是canvas包的问题,之所以一直没有发现是它,是因为出问题的代码里并没有用到这个包,它是在别的地方被引用到的,可能它的二进制模块破坏了node的环境,导致别的代码执行的时候触发了异常导致程序崩溃。

这个问题其实也不是第一次出现了,而且每次都是因为项目中同时有canvas和sharp两个模块才出现问题,在某些版本下不会出问题,某些版本下又会出现不一样的错误,这次就是和上次不一样所以才没能快速发现。

就这点破事,又浪费了我一个晚上,这时候我真想给搞出这bug的人屁股上来一脚。

IIS反向代理站点跳转域名被替换

今天一个破问题浪费我一下午的时间,我一直在找自己代码是不是有什么问题,或者是不是express有什么bug,结果到最后发现原来是iis的问题。

如果是在win上用iis反代站点的话,通常都会用iis的requestRouter插件,在他的设置页面`Application Request Routing`里网上的教程通常都勾着`Reverse rewrite host in response headers`这一项,就是因为这个设置导致后端返回的http头中location指定的跳转地址被替换为了此站点的地址,不知道这是个什么智障操作。

TrueNAS启用pkg包管理器

这是一篇小笔记,truenas默认没法使用pkg install来安装包,会出现以下报错

“`shell
pkg: file:///usr/ports/packages/meta.txz: No such file or directory
…..
pkg: file:///usr/ports/packages/packagesite.txz: No such file or directory
Unable to update repository local
“`

解决方案是进入`/usr/local/etc/pkg/repos/` ,把`local.conf`中`enabled`后的yes改成no,把`FreeBSD.conf`中`enabled`后的no改成yes即可。

 

方案来源 : https://www.justinsilver.com/random/fix-pkg-on-freenas-11-2/