addon@Node.js之新手上路

Nodejs.addon详解 (也叫Node.js 插件)是用像C++Rust等底层语言编写的动态库。它可以被 Node.js 应用程序直接加载和调用,就像一个普通的 JavaScript 模块一样。这些插件通常被编译成一个扩展名为.node的文件。在 JavaScript 代码中,你可以用require()函数来加载这个.node文件,然后使用其中暴露的函数。 阅读详情

  最近要写一个addon插件,所以。。。。

   准备材料:1.安装python;2.安装开发包(下载 | Node.js 中文网);3.安装vscode(windows版本)/ xcode(MAC版本)

  我是在windows下开发,选择vscode。下面的经历都是windows版本,其他系统的忽略

  现在网上的材料大部分不适用于新版的node.js。举个例子:新版的参数多了一个v8::Local<v8::Context> context,很多转换都要用到。以前可以直接args[0]->ToString();现在是不允许了。

  安装好上述3件宝,将下载的hello范例拉到vscode上,选择nan版本,右键“在继承终端模式打开”,输入(1)>>>npm init

然后(2)>>>npm install nan

(3)>>>npm install node-gyp -g

(4)>>>node-gyp configure

(5)>>>node-gyp build  

之后的debug可以选择>>>node-gyp rebuild 取代(5),最后调试>>>node hello.js

上述的hello可以在C++ 插件 | Node.js API 文档看到详细的介绍,我不细说。

搭建好调试环境,接下来就是开动addon定制了。

我这个插件需要调用外部已经写好的DLL,所以要先SetDLLPath(用到windows API "SetDllDirectory"&"GetModuleHandle"&"LoadLibrary"等),网上一堆类似的教程,我不赘述了。js调用可能是

var buf=Buffer.alloc(2048);

buf.write(__dirname+'/dll_path')

addon.jSetDllPath(Object(buf), buf.length)

C++函数SetDLLPath:

void SetDLLPath_C(const Nan::FunctionCallbackInfo<v8::Value>& info)

{

Isolate* isolate = info.GetIsolate();

  v8::Local<v8::Context> context = isolate->GetCurrentContext();

Local<Object> out=Local<Object>::Cast(info[0]);    //直接Buffer类型就Object

  unsigned char *ss = (unsigned char *)node::Buffer::Data(out);

//处理传递的字符串

double arg1 = info[1]->NumberValue(context).FromJust();  //Buffer的大小

//...后面的省略

}

void Init(v8::Local<v8::Object> exports) {

  v8::Local<v8::Context> context = exports->CreationContext();

  exports->Set(context,

               Nan::New("SetDLLPath").ToLocalChecked(),

               Nan::New<v8::FunctionTemplate>(SetDLLPath_C)->GetFunction(context).ToLocalChecked());

}

NODE_MODULE(addon, Init)

这样就完成一个函数的对接。我只学Buffer和Number的传递,其他的String之类的完全摸不到边,工程时间急先这样做了。

上述的代码可以看出,js调用的实际上是暴露的接口字符串,和C的函数接口没啥关系,不过我们习惯写法都是将它们统一的(方便复制粘贴^_^)。同时也看出了新版的Buffer转换其实比旧版的要简单,但是Number转换时需要参数content,所谓的上下文。String也是和Number类似的,只不过缓存UTF8有点问题,我还在研究中。。。。

好了,暂时就这么多!

Node插件开发(1) - 快速入门 在使用Electron开发客户端时,如果现有Node模块所提供的功能无法满足需求,我们可以使用C++开发自定义的Node模块,也称插件(addon)。 Node.js插件的扩展名为`.node`,是二进制文件,其本质上是动态链接库重命名而来,在Windows平台是.dll文件,Linux/Unix平台是.so文件。 阅读详情

相关推荐

Nodejs调用Dll模块的方法

公司项目采用Electron(electronjs.org/ )开发pc应用,会涉及到与底层硬件设备的通信,而sdk封装 基本上都是通过 C++ 动态链接库dll实现的。 有两种方案可供选择: 方案一: 使用node-ffi 方案二: 使用C++编写一个node addon,通过LoadLibrary调用dll 以上两种方案都可以解决dll调用问题,方案选型要个人对C++ 的掌握程度,如果熟悉C++开发,可以直接选择方案二最方便。如果完全不了解C++,那么只能采用方案一。 由于笔主不太懂C++,最终选择第一种方案。 二、什么是node-ffi? ( www.npmjs.com/pack

Node.js Addon编译调试教程(一次成功版)

NodeJs Addon 编译和调试教程,按照文章操作,保证成功!!

lifugui001的专栏 1434

Python与numpy版本兼容性排查指南

本文详细解析了Python与numpy版本兼容性问题,提供了快速诊断和解决版本冲突的实用方法。通过查看版本信息、使用官方兼容性对照表以及降级或升级环境等方案,帮助开发者有效避免常见的报错问题,如'ImportError'和'AttributeError'。文章还介绍了使用虚拟环境和requirements.txt等工程实践,确保项目依赖的稳定性。

weixin_29089057的博客 319

Nodejs 第五十七章(addon)

Nodejs在IO方面拥有极强的能力,但是对CPU密集型任务,会有不足,为了填补这方面的缺点,Nodejs支持c/c++为其编写原生nodejs插件,补充这方面的能力。

qq1195566313的博客 1675

2019美亚杯团体赛刷题 部分题解(1-42、106-116)

文章目录写在前面使用工具刷题1.在黑客路由器里,有一台设备的MAC地址为00:11:6B:47:4D:55,请问它的IP地址是什么?2.在黑客路由器里,发现一设备的IP地址为192.168.0.103,请问该设备为如下哪一个:3.警方已经查证所有连接此router的设备都归黑客所有,根據黑客路由器的訊息,下列哪组(设备---ip)是错误的:4.Hacker现场检获的Windows主机硬盘已成功取证并制作成镜像Win1.E01,下列哪个是其硬盘证据文件的MD5哈希值。5.MD5hash算法会产生一个什么大小的

7ruth0hn的博客 7547

粒子滤波在基于误差状态量的INS/GNSS组合导航中的使用技巧-On Particle Filter based Error-State INS/GNSS Intergrated Navigation

本文面向以15维惯导(INS)误差为状态量,3维位置误差为量测量的INS/GNSS组合导航系统,​在西工大严恭敏老师的开源工具箱中PF相关库函数基础上实现基于粒子滤波(PF)的惯导误差状态量的递推估计,设计了粒子重置环节并强调了其在本特定场景下的重要性。

I33D33I的博客 1742

NodeJS Addon开发

1.环境搭建 npm init npm i --save --dev node-gyp node-addon-api 在package.json中加入如下配置: 在package.json同级目录下创建配置文件binding.gyp: { "targets": [{ "target_name": "smipc", "cflags!": [ "-fno-e...

Luncert的博客 2202

从POI兴趣点获取到ArcGIS中热力图制作

1. POI获取及坐标点转换 POI获取我们要借助下面这个网站↓↓↓ 规划云http://guihuayun.com/poi/ 搜索POI兴趣点并复制兴趣点, 图 新建txt文本文档,粘贴兴趣点 图片 查看后得知,lng为横坐标,lat为纵坐标 文件,另存为csv格式文件,编码为utf—8 打开QGIS,因为我们pol点是从百度地图上获取的,为BD09坐标系,与WGS84有一定偏移【GCJ02:火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。 BD09:为.

qq_43173805的博客 5598

nodejs addon

nodejs和C++配合起来,又能满足前端的快速开发,也能达到核心层的性能要求。 之前也写过用C++写addon的例子。在实际使用过程也遇到了一些问题: 有些场景需要js注册回调函数,供底层调用,这个时候会将回调函数记录v8::Persistent<v8::Function>,实际使用的时候是需要转换为v8::Local<v8::Function>来调用: auto...

最爱吹吹风 1661

ollama接入图像识别大模型

ollama接入图像识别大模型

qq_36437991的博客 2075

windows系统下,如何为comfyui如何安装triton

​ 有些加速插件、模型在安装的时候,比如说sageattention的安装,就需要提前安装triton这个包,不过这个包有点特殊,windows下略微不好装,经常会装失败。 🎠如何安装 之前也有人介绍过,要到github上找个wheel文件,找到对应的版本安装下就好了。 问题是:https://github.com/woct0rdho/triton-windows/releases 这个git地址上,已经找不到wheel文件了... ​

聚梦小课堂 4499

用 Addon 增强 Node.js 和 Electron 应用的原生能力

前言Node.js Addon 是 Node.js 中为 JavaScript 环境提供 C/C++ 交互能力的机制。其形态十分类似 Java 的 JNI,都是通过提供一套 C/C++ SDK,用于在 C/C++ 中创建函数方法、进行数据转换,以便 JavaScript / Java 等语言进行调用。这样编写的代码通常叫做 Bindings。此外还有基于 C ABI Calling Convent...

字节跳动技术团队官方博客 2万+

【从零开始学习 UVM】1.2、UVM 概述 —— UVM Installation(UVM 安装)

【从零开始学习 UVM】1.2、UVM 概述 —— UVM Installation(UVM 安装)

努力,加油每一天鸭~ 1946

零基础开发 Node.js Addons 插件:Hello Node-API

Node-API(以前称为 N-API)是 Node.js 官方提供的一个用来编写 C/C++ 插件的稳定模块。不同版本的 Node.js 只要遵循的 应用二进制接口(ABI) 的版本是一...

weixin_44829437的博客 1117

Android16 RK3576修改亮度调节为线性调节

文章摘要: 本文分析了Android系统中亮度调节的非线性问题,并提供了线性化改造方案。首先通过追踪Settings和SystemUI代码,发现亮度调节使用了BrightnessUtils类中的非线性Gamma空间转换算法。然后重点修改了BrightnessUtils类,将原有的Hybrid Log Gamma(HLG)算法替换为简单的线性映射公式。最后在自定义工具窗口中实现了基于系统标准接口的亮度调节功能,通过SeekBar的0-100%百分比值线性映射到1-255的系统亮度值。改造后的亮度调节更加直观,

tzj1058756809的博客 76

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

自定义NodeJS-C++ Addons使用说明

自定义NodeJS-C++ Addons使用说明 Windows 流程 Step.01 编译环境搭建 参照Github-nodejs/node-gyp使用选择: windows-build-tools 注意,需要使用管理员权限打开cmd等 Visual Studio Build Tools 或下载完整的Visual Studio(其中也需要包含对应的build tool) 安装对应的Pytho...

vivisoul的专栏 1029

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NodeJs使用Addon调用C++

本文介绍的是NodeJs使用node-addon-api调用C++的方法node-addon-api是一个C++封装,基于N-API构建,目的是提供一个更高级和更易用的接口,但它仍然依赖N-API。

qq_36651243的博客 1582

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

探索 Node.js 与 C++ 的绑定:使用 node-addon-api

在 Node.js 中使用 C++ 进行绑定是一种强大的方式,可以充分利用 C++ 的性能优势。在本文中,我们将探讨如何使用来实现这一目标。Node.js 是一个基于 JavaScript 的平台,它使得开发人员能够使用 JavaScript 进行高性能的网络应用开发。然而,有时我们可能需要更高的性能,这时我们可以考虑使用 C++。通过将关键部分用 C++ 编写并绑定到 Node.js 中,我们可以获得更好的性能。是一个为 Node.js 编写的 C++ 插件提供的高级 C++ API。

一览无遗 3720

VSCode Terminal无法运行node以及node-gyp等指令

运行node-gyp等指令出现因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。用管理员权限打开PowerShell,输入set-ExecutionPolicy RemoteSigned,按Y确认即可。无法使用node指令,使用管理员权限启动VSCode即可,或者右键VSCode属性,修改兼容性中使用管理员权限打开。此类错误,需要修改执行策略来执行不信任脚本。

qq_36651243的博客 668

关于前端vue框架项目环境搭建-node-sass & Python &Vscode&node-gyp

这些是本媛由于客观原因在一个月内反复配置三次前端环境(三台不同电脑)所遇到的问题回顾,值得重点一提的是,前端环境配置特别在意的是版本对应。所以版本选择上,需要慎重!基本上的报错都可能是版本问题,在每次重新加载依赖之前,保险起见,删除项目中的node-modules文件夹,同时执行一下清除缓存命令 (来自前端朋友邓邓的友好提示)其次是淘宝镜像的原因,一定注意淘宝镜像已经发生改变npmmirror 镜像站。

amily_lisa的博客 2102

Nodejs 使用 C/C++ addons with Node-API

nodejs 使用 c++ 扩展

w55100的博客 3522

JavaScript 1 ,NodeJS的安装和使用,NodeJS安装过程,详细步骤教学,及配置环境变量(nodejs安装使用步骤)

⭐Node.js安装过程,详细步骤教学,及配置环境变量。此电脑>属性>高级系统设置>环境变量>系统变量>选择变量Path>点击编辑>点击新建(输入路径:C:\Program Files\nodejs\),然后记得确定保存。

AI Agent 全栈架构师(AI + GIS + Backend)& 数字芯片系统架构师(FPGA),NorthCity Smile的博客(NcSmile,博主域名:https://ncmile.blog.youkuaiyun.com) 5618

NodeJS C++ Addons基础

NodeJS C++插件是一种动态链接库,采用C/C++语言编写,可以通过require()将插件加载进NodeJS中进行使用。利用V8提供的API,可以实现JavaScript和C++的互相调用,打通JavaScript和C++之间的接口。在做一些高性能或者底层模块的时候,需要用到一些C++库,NodeJS C++插件可以帮助我们封装这些C++库的接口,使得JavaScript具备调用C++库的能力。本文将记录利用基础的V8 API编写NodeJS C++插件的过程,实现C++和JavaScript之间的

woaitingting1985的博客 1023

使用Node.js Addon API指南

Node.js Addon API项目的目录结构有助于理解和组织其功能组件。以下是关键目录及其说明: ### `doc` 该目录存储API参考和其他技术文档。 ### `src` 这个目录包含了项目的核心源代码。Addon API提供了用于在C/C++中编写Node.js插件的抽象层。 ### `test` 测试目录包含单元测试和其他验证工具以确保代码质量和功能正确性。 ### `exam...

gitblog_00218的博客 605

零基础开发 Node.js Addons 插件:参数与返回值处理

上一篇回顾 零基础开发 Node.js Addons 插件:Hello Node-API。本篇介绍使用 Node-API 为 Node.js 开发基于 C 的 Addons 时,如何接收与...

weixin_44829437的博客 4967

使用C++开发nodejs扩展模块

Node.js 是基于 C++ 开发的(底层用 chrome v8 做 js 引擎 && libuv 完成事件循环机制),因此它的所有底层头文件暴露的 API 也都是适用于 C++ 的。上一节中提到 nodejs 模块寻径的时候会默认找 .node 为后缀名的模块,实际上这是个 C++ 模块的二进制文件,即编译好之后的 C++ 模块,本质上是个动态链接库。例如 (Windows dll/Linux so/Unix dylib)

一名高级工程师的博客 2971
上一篇: 重视多线程的堆栈问题
下一篇: 编程实现NSTextView中选择的文字切换粗体
狼风123
博客等级 码龄19年 1058粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值