【C# AT Lib】3:AT Command

本文介绍了在C#中构建AT Command框架的过程,包括定义ResultCode枚举、ResponseExpectation类来设置期望响应,以及AtCommand和AtCommandBuilder类用于简化命令构造。

我们在设计AT Command,需要把期望AT Response是什么样的信息放进去,这样在底层进行AT通讯的时候就可以自动加入Retry功能。

 

定义ResultCode枚举变量

    public enum ResultCode
    {
        OK,
        ERROR
    }

 

定义ResponseExpectation类

  • 告知AT Response需不需要包含期望的Result Code
  • 告知AT Response中对于总体Data Lines有什么期许
  • 告知AT Response中对于某一行Data Line有什么期许
    public class ResponseExpectation
    {
        public ResultCode? ExpectedResultCode { get; set; }

        public Predicate<string[]> AllDataLinesPredicate { get; set; }

        public Predicate<string>[] AnyDataLinePredicates { get; set; }

        public bool Accepts(ResultCode? resultCode, string[] dataLines)
        {
            return Accepts(resultCode) && Accepts(dataLines);
        }

        private bool Accepts(ResultCode? resultCode)
        {
            if (!ExpectedResultCode.HasValue)
                return true;

            return ExpectedResultCode == resultCode;
        }

        private bool Accepts(string[] dataLines)
        {
            if (!AllDataLinesPredicateAccepts(dataLines))
                return false;

            if (!AnyDataLinePredicatesAccept(dataLines))
                return false;

            return true;
        }

        private bool AllDataLinesPredicateAccepts(string[] dataLines)
        {
            return AllDataLinesPredicate == null || AllDataLinesPredicate(dataLines);
        }

        private bool AnyDataLinePredicatesAccept(string[] dataLines)
        {
            return AnyDataLinePredicates.All(
                dataLinePredicate => dataLines.Any(line => dataLinePredicate(line)));
        }
    }

 

定义AtCommand类

    public class AtCommand
    {
        public string RawCommand { get; set; }

        public string SuffixedRawCommand
        {
            get
            {
                const string suffix = "\r";
                return RawCommand + suffix;
            }
        }

        public ResponseExpectation ResponseExpectation { get; set; }

        public override string ToString()
        {
            return RawCommand;
        }
    }

定义AtCommandBuilder类

因为AtCommand对象在构造的时候相对有些复杂,于是我们用一个单独的AtCommandBuilder类去帮助构造AtCommand对象。

    public class AtCommandBuilder
    {
        private string _rawCommand;
        private ResultCode? _expectedResultCode;
        private Predicate<string[]> _allDataLinesPredicate;
        private readonly List<Predicate<string>> _anyDataLinePredicates = new List<Predicate<string>>();

        public AtCommandBuilder WithRawCommand(string rawCommand)
        {
            if (string.IsNullOrWhiteSpace(rawCommand))
                throw new ArgumentException("Raw command can't be Null or WhiteSpace.", "rawCommand");

            _rawCommand = rawCommand.Trim();

            return this;
        }

        public AtCommandBuilder WithExpectedResultCode(ResultCode expectedResultCode)
        {
            _expectedResultCode = expectedResultCode;
            return this;
        }

        public AtCommandBuilder WithExpectedOkResultCode()
        {
            return WithExpectedResultCode(ResultCode.OK);
        }

        public AtCommandBuilder WithAllDataLinesPredicate(Predicate<string[]> predicate)
        {
            _allDataLinesPredicate = predicate;
            return this;
        }

        public AtCommandBuilder WithAnyDataLinePredicate(Predicate<string> predicate)
        {
            _anyDataLinePredicates.Add(predicate);
            return this;
        }

        public AtCommandBuilder WithAnyDataLinePredicateStartsWith(string startCriterion)
        {
            return WithAnyDataLinePredicate(
                dateLine => dateLine.StartsWith(startCriterion, StringComparison.CurrentCultureIgnoreCase));
        }

        public AtCommand Build()
        {
            return new AtCommand
            {
                RawCommand = _rawCommand,
                ResponseExpectation = new ResponseExpectation
                {
                    ExpectedResultCode = _expectedResultCode,
                    AllDataLinesPredicate = _allDataLinesPredicate,
                    AnyDataLinePredicates = _anyDataLinePredicates.ToArray()
                }
            };
        }
    }

 

Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeInitializationException: The type initializer for &#39;BD.Common.VersionTracking2&#39; threw an exception. ---> System.TypeInitializationException: The type initializer for &#39;SQLite.SQLiteConnection&#39; threw an exception. ---> System.DllNotFoundException: Unable to load shared library &#39;e_sqlite3&#39; or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you&#39;re using glibc, consider setting the LD_DEBUG environment variable: /opt/steam++/assemblies/e_sqlite3.so: cannot open shared object file: No such file or directory /opt/steam++/dotnet/shared/Microsoft.NETCore.App/8.0.0/e_sqlite3.so: cannot open shared object file: No such file or directory /opt/steam++/assemblies/libe_sqlite3.so: cannot open shared object file: No such file or directory /opt/steam++/dotnet/shared/Microsoft.NETCore.App/8.0.0/libe_sqlite3.so: cannot open shared object file: No such file or directory /opt/steam++/assemblies/e_sqlite3: cannot open shared object file: No such file or directory /opt/steam++/dotnet/shared/Microsoft.NETCore.App/8.0.0/e_sqlite3: cannot open shared object file: No such file or directory /opt/steam++/assemblies/libe_sqlite3: cannot open shared object file: No such file or directory /opt/steam++/dotnet/shared/Microsoft.NETCore.App/8.0.0/libe_sqlite3: cannot open shared object file: No such file or directory at System.Runtime.InteropServices.NativeLibrary.LoadLibraryByName(String libraryName, Assembly assembly, Nullable`1 searchPath, Boolean throwOnError) at BD.WTTS.GlobalDllImportResolver.Delegate(String libraryName, Assembly assembly, Nullable`1 searchPath) at System.Runtime.InteropServices.NativeLibrary.LoadLibraryCallbackStub(String libraryName, Assembly assembly, Boolean hasDllImportSearchPathFlags, UInt32 dllImportSearchPathFlags) at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_libversion_number() at SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number() at SQLitePCL.raw.SetProvider(ISQLite3Provider imp) at SQLitePCL.Batteries_V2.Init() at SQLite.SQLiteConnection..cctor() --- End of inner exception stack trace --- at SQLite.SQLiteConnection..ctor(String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks) at BD.Common.Repositories.Abstractions.Repository.get_ConnectionSync() at BD.Common.Services.Implementation.PreferencesPlatformServiceImpl..ctor() at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType) at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at BD.Common.Services.IPreferencesPlatformService.get_Instance() at BD.Common.VersionTracking2.InitVersionTracking() at BD.Common.VersionTracking2..cctor() --- End of inner exception stack trace --- at BD.Common.VersionTracking2.Track() at BD.WTTS.UI.Views.Windows.AppSplashScreen.<>c.<<FluentAvalonia-UI-Windowing-IApplicationSplashScreen-RunTasks>b__14_0>d.MoveNext() --- End of stack trace from previous location --- at FluentAvalonia.UI.Windowing.SplashScreenContext.RunJobs() at FluentAvalonia.UI.Windowing.AppWindow.OnOpened(EventArgs e) at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state) at Avalonia.Threading.SendOrPostCallbackDispatcherOperation.InvokeCore() at Avalonia.Threading.DispatcherOperation.Execute() at Avalonia.Threading.Dispatcher.ExecuteJob(DispatcherOperation job) at Avalonia.Threading.Dispatcher.ExecuteJobsCore(Boolean fromExplicitBackgroundProcessingCallback) at Avalonia.Threading.Dispatcher.OnOSTimer() at Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationToken) at Avalonia.Threading.DispatcherFrame.Run(IControlledDispatcherImpl impl) at Avalonia.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken) at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime2.Start(String[] args) at BD.WTTS.Program.StartUIApplication() at BD.WTTS.Startup.<ConfigureCommands>b__0_12() at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr) --- End of inner exception stack trace --- at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context) at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext() --- End of stack trace from previous location --- at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
最新发布
11-26
你是一个unity专家 这个问题如何解决数据库路径 URI=file:/storage/emulated/0/Android/data/com.cmgames.CoinCars/files/chatdata.db 13007-21 07:30:10.553 18694 18874 D nativeloader: Load /data/app/~~sTWOKcK788AlzkZ6vsXqEg==/com.cmgames.CoinCars-Fel0V_2Qo_-P7BgnH0L53A==/lib/arm64/libsqlite3.so using class loader ns clns-4 (caller=/data/app/~~sTWOKcK788AlzkZ6vsXqEg==/com.cmgames.CoinCars-Fel0V_2Qo_-P7BgnH0L53A==/base.apk!classes3.dex): ok 13107-21 07:30:10.595 18694 18874 I Unity : result 1 13207-21 07:30:12.093 18694 18874 E Unity : Got the fucking exception :c# exception:SQLite error 13307-21 07:30:12.093 18694 18874 E Unity : near "ari": syntax error,stack: at Mono.Data.Sqlite.SQLite3.Prepare (Mono.Data.Sqlite.SqliteConnection cnn, System.String strSql, Mono.Data.Sqlite.SqliteStatement previous, System.UInt32 timeoutMS, System.String& strRemain) [0x00000] in <00000000000000000000000000000000>:0 13407-21 07:30:12.093 18694 18874 E Unity : at Mono.Data.Sqlite.SqliteCommand.BuildNextCommand () [0x00000] in <00000000000000000000000000000000>:0 13507-21 07:30:12.093 18694 18874 E Unity : at Mono.Data.Sqlite.SqliteDataReader.NextResult () [0x00000] in <00000000000000000000000000000000>:0 13607-21 07:30:12.093 18694 18874 E Unity : at Mono.Data.Sqlite.SqliteCommand.ExecuteReader (System.Data.CommandBehavior behavior) [0x00000] in <00000000000000000000000000000000>:0 13707-21 07:30:12.093 18694 18874 E Unity : at Mono.Data.Sqlite.SqliteCommand.ExecuteNonQuery () [0x00000] in <00000000000000000000000000000000>:0 13807-21 07:30:12.093 18694 18874 E Unity : at CustomSqlite.LChatSqlChatData.SetChatData (CustomSqlite.LChatSqlDataBase+SqlChatData chatData) [0x00000] in <00000000000000000000000000000000>:0 13907-21 07:30:12.093 18694 18874 E Unity : at CustomSqlite.LChatSqliteManager.SetChatData (System.String jsonData) [0x00000] i
07-22
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting dlib==20.0.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/28/f4/f8949b18ec1df2ef05fc2ea1d1dd82ff2d050b8704b7d0d088017315c221/dlib-20.0.0.tar.gz (3.3 MB) Installing build dependencies: started Installing build dependencies: finished with status &#39;done&#39; Getting requirements to build wheel: started Getting requirements to build wheel: finished with status &#39;done&#39; Preparing metadata (pyproject.toml): started Preparing metadata (pyproject.toml): finished with status &#39;done&#39; Building wheels for collected packages: dlib Building wheel for dlib (pyproject.toml): started Building wheel for dlib (pyproject.toml): finished with status &#39;error&#39; Failed to build dlib error: subprocess-exited-with-error Building wheel for dlib (pyproject.toml) did not run successfully. exit code: 1 [79 lines of output] running bdist_wheel running build running build_ext <string>:163: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead. Building extension for Python 3.11.9 (tags/v3.11.9:de54cf5, Apr 2 2024, 10:12:12) [MSC v.1938 64 bit (AMD64)] Invoking CMake setup: &#39;cmake C:\Users\Narie\AppData\Local\Temp\pip-install-x19b5ukg\dlib_982d0a60ebba4807aaec926af963c900\tools\python -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=C:\Users\Narie\AppData\Local\Temp\pip-install-x19b5ukg\dlib_982d0a60ebba4807aaec926af963c900\build\lib.win-amd64-cpython-311 -DPYTHON_EXECUTABLE=D:\Work\openface-master\.venv\Scripts\python.exe -DDLIB_USE_FFMPEG=OFF -DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=C:\Users\Narie\AppData\Local\Temp\pip-install-x19b5ukg\dlib_982d0a60ebba4807aaec926af963c900\build\lib.win-amd64-cpython-311 -A x64&#39; -- Building for: NMake Makefiles CMake Error at CMakeLists.txt:5 (message): !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! You must use Visual Studio to build a python extension on windows. If you are getting this error it means you have not installed Visual C++. Note that there are many flavors of Visual Studio, like Visual Studio for C# development. You need to install Visual Studio for C++. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- Configuring incomplete, errors occurred! Traceback (most recent call last): File "D:\Work\openface-master\.venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 353, in <module> main() File "D:\Work\openface-master\.venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 335, in main json_out[&#39;return_val&#39;] = hook(**hook_input[&#39;kwargs&#39;]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Work\openface-master\.venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 251, in build_wheel return _build_backend().build_wheel(wheel_directory, config_settings, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\build_meta.py", line 435, in build_wheel return _build([&#39;bdist_wheel&#39;, &#39;--dist-info-dir&#39;, str(metadata_directory)]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\build_meta.py", line 423, in _build return self._build_with_temp_dir( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\build_meta.py", line 404, in _build_with_temp_dir self.run_setup() File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\build_meta.py", line 317, in run_setup exec(code, locals()) File "<string>", line 243, in <module> File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\__init__.py", line 115, in setup return distutils.core.setup(**attrs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\core.py", line 186, in setup return run_commands(dist) ^^^^^^^^^^^^^^^^^^ File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\core.py", line 202, in run_commands dist.run_commands() File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 1002, in run_commands self.run_command(cmd) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\dist.py", line 1102, in run_command super().run_command(command) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 1021, in run_command cmd_obj.run() File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\command\bdist_wheel.py", line 370, in run self.run_command("build") File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\cmd.py", line 357, in run_command self.distribution.run_command(command) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\dist.py", line 1102, in run_command super().run_command(command) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 1021, in run_command cmd_obj.run() File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\command\build.py", line 135, in run self.run_command(cmd_name) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\cmd.py", line 357, in run_command self.distribution.run_command(command) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\dist.py", line 1102, in run_command super().run_command(command) File "C:\Users\Narie\AppData\Local\Temp\pip-build-env-wqyxf4c7\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 1021, in run_command cmd_obj.run() File "<string>", line 168, in run File "<string>", line 206, in build_extension File "D:\develop\Python\Lib\subprocess.py", line 413, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command &#39;[&#39;cmake&#39;, &#39;C:\\Users\\Narie\\AppData\\Local\\Temp\\pip-install-x19b5ukg\\dlib_982d0a60ebba4807aaec926af963c900\\tools\\python&#39;, &#39;-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=C:\\Users\\Narie\\AppData\\Local\\Temp\\pip-install-x19b5ukg\\dlib_982d0a60ebba4807aaec926af963c900\\build\\lib.win-amd64-cpython-311&#39;, &#39;-DPYTHON_EXECUTABLE=D:\\Work\\openface-master\\.venv\\Scripts\\python.exe&#39;, &#39;-DDLIB_USE_FFMPEG=OFF&#39;, &#39;-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=C:\\Users\\Narie\\AppData\\Local\\Temp\\pip-install-x19b5ukg\\dlib_982d0a60ebba4807aaec926af963c900\\build\\lib.win-amd64-cpython-311&#39;, &#39;-A&#39;, &#39;x64&#39;]&#39; returned non-zero exit status 1. [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for dlib ERROR: Could not build wheels for dlib, which is required to install pyproject.toml-based projects [notice] A new release of pip is available: 23.2.1 -> 25.2 [notice] To update, run: python.exe -m pip install --upgrade pip
09-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值