MicroPython字节码文件——mpy文件解析

参考文档:MicroPython .mpy files

前置注意点

  • mpy文件的二进制文件是一种嵌套格式。先描述外层模块,然后描述子模块。
  • 使用vint(变长编码)表示整数,当前字节最高位置1表示还有后续字节。
  • 不同版本的MicroPython对应的mpy文件格式不一定兼容。

MicroPython项目提供了一个脚本mpy-tool.py来解析mpy文件的内容,所以想知道mpy文件的结构、具体包含了哪些信息,可以阅读下这个脚本源码。

You can inspect the contents of a .mpy file by using mpy-tool.py, for
example (run from the root of the main MicroPython repository):
$ ./tools/mpy-tool.py -xd myfile.mpy

可以自行下载阅读器(比如winHex),查看mpy文件的十六进制码。
在这里插入图片描述

mpy文件内容概览

全局的mpy文件内容构成如图,首先是4个字节的header,接着是2个vint,分别表示qstr和obj的数量。
在这里插入图片描述

Header

4个字节的头部,用于标识mpy文件和版本、CPU架构要求、小整型的位数。
在这里插入图片描述

qstr and constant objects tables

在这里插入图片描述

qstr表

在这个表中,每个qstr对象都由一个表示长度的vint和后续数据组成。

qstr unit

在这里插入图片描述
注意,mpy文件里的len是实际qstr长度的2倍。这是由于最低位用来判别是否为static qstr。比如字节码为 0a 416c 6963 6500,第一个字节0a最高位为0,表示无后续字节,则qstr长度为a/2 = 5。后面跟着5个字节为qstr的内容“Alice",第六个字节00表示字符串的结束。

def read_qstr(reader, segments):start_pos = reader.tell()ln = reader.read_uint()if ln & 1:# static qstrq = global_qstrs.get_by_index(ln >> 1)segments.append(MPYSegment(MPYSegment.META, q.str, start_pos, start_pos))return qln >>= 1start_pos = reader.tell()data = str_cons(reader.read_bytes(ln), "utf8")reader.read_byte()  # read and discard null terminatorsegments.append(MPYSegment(MPYSegment.QSTR, data, start_pos, reader.tell()))return global_qstrs.add(data)

obj表 //todo: 待补充

def read_obj(reader, segments):obj_type = reader.read_byte()if obj_type == MP_PERSISTENT_OBJ_FUN_TABLE:return MPFunTable()elif obj_type == MP_PERSISTENT_OBJ_NONE:return Noneelif obj_type == MP_PERSISTENT_OBJ_FALSE:return Falseelif obj_type == MP_PERSISTENT_OBJ_TRUE:return Trueelif obj_type == MP_PERSISTENT_OBJ_ELLIPSIS:return Ellipsiselif obj_type == MP_PERSISTENT_OBJ_TUPLE:ln = reader.read_uint()return tuple(read_obj(reader, segments) for _ in range(ln))else:ln = reader.read_uint()start_pos = reader.tell()buf = reader.read_bytes(ln)if obj_type in (MP_PERSISTENT_OBJ_STR, MP_PERSISTENT_OBJ_BYTES):reader.read_byte()  # read and discard null terminatorif obj_type == MP_PERSISTENT_OBJ_STR:obj = str_cons(buf, "utf8")if len(obj) < PERSISTENT_STR_INTERN_THRESHOLD:if not global_qstrs.find_by_str(obj):global_qstrs.add(obj)elif obj_type == MP_PERSISTENT_OBJ_BYTES:obj = bufelif obj_type == MP_PERSISTENT_OBJ_INT:obj = int(str_cons(buf, "ascii"), 10)elif obj_type == MP_PERSISTENT_OBJ_FLOAT:obj = float(str_cons(buf, "ascii"))elif obj_type == MP_PERSISTENT_OBJ_COMPLEX:obj = complex(str_cons(buf, "ascii"))else:raise MPYReadError(reader.filename, "corrupt .mpy file")segments.append(MPYSegment(MPYSegment.OBJ, obj, start_pos, reader.tell()))return obj

obj对象类型

MP_PERSISTENT_OBJ_FUN_TABLE = 0
MP_PERSISTENT_OBJ_NONE = 1
MP_PERSISTENT_OBJ_FALSE = 2
MP_PERSISTENT_OBJ_TRUE = 3
MP_PERSISTENT_OBJ_ELLIPSIS = 4
MP_PERSISTENT_OBJ_STR = 5
MP_PERSISTENT_OBJ_BYTES = 6
MP_PERSISTENT_OBJ_INT = 7
MP_PERSISTENT_OBJ_FLOAT = 8
MP_PERSISTENT_OBJ_COMPLEX = 9
MP_PERSISTENT_OBJ_TUPLE = 10

raw code header

在这里插入图片描述
字节码的头部是一个vint类型,最低两位表示代码类型

kind_len = reader.read_uint() # 读取一个vint
kind = (kind_len & 3) + MP_CODE_BYTECODE  # 取低2位加上MP_CODE_BYTECODE个偏移量

4种代码类型定义如下

MP_CODE_BYTECODE = 2
MP_CODE_NATIVE_PY = 3
MP_CODE_NATIVE_VIPER = 4
MP_CODE_NATIVE_ASM = 5

低第三位表示有无子模块,0表示无子模块,1表示有子模块。

has_children = (kind_len >> 2) & 1

其余位表示长度,注意字节的最高位只用于表示有无后续字节,不算进长度表示的位中。
头部后面跟着的就是字节码的内容了。


示例

最后放个py源码和生成的mpy字节码供大家参考学习。

class Wallet:def __init__(self, owner_name, balance=0):self.owner_name = owner_nameself.balance = balancedef deposit(self, amount):if amount > 0:self.balance += amountprint(f"Deposited ${amount}. New balance: ${self.balance}")else:print("Invalid deposit amount.")def withdraw(self, amount):if amount > 0 and self.balance >= amount:self.balance -= amountprint(f"Withdrew ${amount}. New balance: ${self.balance}")else:print("Invalid or insufficient funds for withdrawal.")def transfer(self, recipient_wallet, amount):if self.balance >= amount and recipient_wallet is not self:if amount > 0:self.withdraw(amount)recipient_wallet.deposit(amount)print(f"Transferred ${amount} to {recipient_wallet.owner_name}.")else:print("Invalid transfer amount.")else:print("Insufficient funds or invalid recipient.")def check_balance(self):print(f"Current balance: ${self.balance}")# Example usage:
# Create two wallet instances
wallet1 = Wallet("Alice", 100)
wallet2 = Wallet("Bob", 50)# Deposit money into wallet1
wallet1.deposit(50)# Withdraw money from wallet1
wallet1.withdraw(20)# Transfer money from wallet1 to wallet2
wallet1.transfer(wallet2, 30)# Check balance of wallet1 and wallet2
wallet1.check_balance()
wallet2.check_balance()
00000000: 4d06 001f 1608 1c77 616c 6c65 745f 7465  M......wallet_te  wallet_test.py
00000010: 7374 2e70 7900 0f0c 5761 6c6c 6574 000a  st.py...Wallet..  <module> Wallet
00000020: 416c 6963 6500 0642 6f62 000e 6465 706f  Alice..Bob..depo  Alice Bob deposit
00000030: 7369 7400 1077 6974 6864 7261 7700 1074  sit..withdraw..t  withdraw transfer
00000040: 7261 6e73 6665 7200 1a63 6865 636b 5f62  ransfer..check_b  check_balance
00000050: 616c 616e 6365 0023 146f 776e 6572 5f6e  alance.#.owner_n  __init__ owner_name
00000060: 616d 6500 0e62 616c 616e 6365 0081 290e  ame..balance..).  balance format
00000070: 7761 6c6c 6574 3100 0e77 616c 6c65 7432  wallet1..wallet2  wallet1 wallet2
00000080: 002f 2d35 8213 0c61 6d6f 756e 7400 8177  ./-5...amount..w  __name__ __module__ __qualname__ self amount print
00000090: 2072 6563 6970 6965 6e74 5f77 616c 6c65   recipient_walle  recipient_wallet
000000a0: 7400 051f 4465 706f 7369 7465 6420 247b  t...Deposited ${  Deposited ${}. New balance: ${}
000000b0: 7d2e 204e 6577 2062 616c 616e 6365 3a20  }. New balance:  
000000c0: 247b 7d00 0517 496e 7661 6c69 6420 6465  ${}...Invalid de  Invalid deposit amount.
000000d0: 706f 7369 7420 616d 6f75 6e74 2e00 051e  posit amount.... 
000000e0: 5769 7468 6472 6577 2024 7b7d 2e20 4e65  Withdrew ${}. Ne  Withdrew ${}. New balance: ${}
000000f0: 7720 6261 6c61 6e63 653a 2024 7b7d 0005  w balance: ${}.. 
00000100: 2d49 6e76 616c 6964 206f 7220 696e 7375  -Invalid or insu  Invalid or insufficient funds for withdrawal.
00000110: 6666 6963 6965 6e74 2066 756e 6473 2066  fficient funds f 
00000120: 6f72 2077 6974 6864 7261 7761 6c2e 0005  or withdrawal... 
00000130: 1654 7261 6e73 6665 7272 6564 2024 7b7d  .Transferred ${}  Transferred ${} to {}.
00000140: 2074 6f20 7b7d 2e00 0518 496e 7661 6c69   to {}....Invali  Invalid transfer amount.
00000150: 6420 7472 616e 7366 6572 2061 6d6f 756e  d transfer amoun 
00000160: 742e 0005 2849 6e73 7566 6669 6369 656e  t...(Insufficien  Insufficient funds or invalid recipient.
00000170: 7420 6675 6e64 7320 6f72 2069 6e76 616c  t funds or inval 
00000180: 6964 2072 6563 6970 6965 6e74 2e00 0514  id recipient.... 
00000190: 4375 7272 656e 7420 6261 6c61 6e63 653a  Current balance:  Current balance: ${}
000001a0: 2024 7b7d 0085 2418 1201 8923 2b6a 6968   ${}..$....#+jih  <module>
000001b0: 6a27 5432 0010 0234 0216 0211 0210 0322  j'T2...4......." 
000001c0: 8064 3402 160d 1102 1004 2232 3402 160e  .d4......."24... 
000001d0: 110d 1405 2232 3601 5911 0d14 0694 3601  ...."26.Y.....6. 
000001e0: 5911 0d14 0711 0e9e 3602 5911 0d14 0836  Y.......6.Y....6 
000001f0: 0059 110e 1408 3600 5951 6301 8274 0814  .Y....6.YQc..t..  Wallet
00000200: 0228 6820 8407 8407 840b 110f 1610 1002  .(h ............ 
00000210: 1611 802a 0153 3300 1609 3201 1605 3202  ...*.S3...2...2. 
00000220: 1606 3203 1607 3204 1608 5163 0581 18a3  ..2...2...Qc....  __init__
00000230: 010c 0912 0a0b 4024 b1b0 180a b2b0 180b  ......@$........ 
00000240: 5163 8310 3210 0512 1360 6025 2951 b180  Qc..2....``%)Q..  deposit
00000250: d844 5ab0 5713 0bb1 e55a 180b 1214 2300  .DZ.W....Z....#. 
00000260: 140c b1b0 130b 3602 3401 5942 4712 1423  ......6.4.YBG..# 
00000270: 0134 0159 5163 8348 3210 0612 1380 0d2c  .4.YQc.H2......,  withdraw
00000280: 2951 b180 d844 61b0 130b b1db 445a b057  )Q...Da.....DZ.W 
00000290: 130b b1e6 5a18 0b12 1423 0214 0cb1 b013  ....Z....#...... 
000002a0: 0b36 0234 0159 4247 1214 2303 3401 5951  .6.4.YBG..#.4.YQ 
000002b0: 6385 083b 1807 1215 1380 142d 2527 2751  c..;.......-%''Q  transfer
000002c0: 49b0 130b b2db 4473 b1b0 ded3 446d b280  I.....Ds....Dm.. 
000002d0: d844 5fb0 1406 b236 0159 b114 05b2 3601  .D_....6.Y....6. 
000002e0: 5912 1423 0414 0cb2 b113 0a36 0234 0159  Y..#.......6.4.Y 
000002f0: 4247 1214 2305 3401 5942 4712 1423 0634  BG..#.4.YBG..#.4 
00000300: 0159 5163 8130 2108 0812 801f 1214 2307  .YQc.0!.......#.  check_balance
00000310: 140c b013 0b36 0134 0159 5163            .....6.4.YQc mpy_source_file: wallet_test.mpy
source_file: wallet_test.py
header: 4d:06:00:1f
qstr_table[22]:wallet_test.py<module>WalletAliceBobdepositwithdrawtransfercheck_balance__init__owner_namebalanceformatwallet1wallet2__name____module____qualname__selfamountprintrecipient_wallet
obj_table: ['Deposited ${}. New balance: ${}', 'Invalid deposit amount.', 'Withdrew ${}. New balance: ${}', 'Invalid or insufficient funds for withdrawal.', 'Transferred ${} to {}.', 'Invalid transfer amount.', 'Insufficient funds or invalid recipient.', 'Current balance: ${}']
simple_name: <module>raw bytecode: 84 18:12:01:89:23:2b:6a:69:68:6a:27:54:32:00:10:02:34:02:16:02:11:02:10:03:22:80:64:34:02:16:0d:11:02:10:04:22:32:34:02:16:0e:11:0d:14:05:22:32:36:01:59:11:0d:14:06:94:36:01:59:11:0d:14:07:11:0e:9e:36:02:59:11:0d:14:08:36:00:59:11:0e:14:08:36:00:59:51:63prelude: (4, 0, 0, 0, 0, 0)args: []line info: 89:23:2b:6a:69:68:6a:2754          LOAD_BUILD_CLASS 32:00       MAKE_FUNCTION 010:02       LOAD_CONST_STRING Wallet34:02       CALL_FUNCTION 216:02       STORE_NAME Wallet11:02       LOAD_NAME Wallet10:03       LOAD_CONST_STRING Alice22:80:64    LOAD_CONST_SMALL_INT 10034:02       CALL_FUNCTION 216:0d       STORE_NAME wallet111:02       LOAD_NAME Wallet10:04       LOAD_CONST_STRING Bob22:32       LOAD_CONST_SMALL_INT 5034:02       CALL_FUNCTION 216:0e       STORE_NAME wallet211:0d       LOAD_NAME wallet114:05       LOAD_METHOD deposit22:32       LOAD_CONST_SMALL_INT 5036:01       CALL_METHOD 159          POP_TOP 11:0d       LOAD_NAME wallet114:06       LOAD_METHOD withdraw94          LOAD_CONST_SMALL_INT 20 36:01       CALL_METHOD 159          POP_TOP 11:0d       LOAD_NAME wallet114:07       LOAD_METHOD transfer11:0e       LOAD_NAME wallet29e          LOAD_CONST_SMALL_INT 30 36:02       CALL_METHOD 259          POP_TOP 11:0d       LOAD_NAME wallet114:08       LOAD_METHOD check_balance36:00       CALL_METHOD 059          POP_TOP 11:0e       LOAD_NAME wallet214:08       LOAD_METHOD check_balance36:00       CALL_METHOD 059          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: ['Wallet']
simple_name: Walletraw bytecode: 46 08:14:02:28:68:20:84:07:84:07:84:0b:11:0f:16:10:10:02:16:11:80:2a:01:53:33:00:16:09:32:01:16:05:32:02:16:06:32:03:16:07:32:04:16:08:51:63prelude: (2, 0, 0, 0, 0, 0)args: []line info: 28:68:20:84:07:84:07:84:0b11:0f       LOAD_NAME __name__16:10       STORE_NAME __module__10:02       LOAD_CONST_STRING Wallet16:11       STORE_NAME __qualname__80          LOAD_CONST_SMALL_INT 0 2a:01       BUILD_TUPLE 153          LOAD_NULL 33:00       MAKE_FUNCTION_DEFARGS 016:09       STORE_NAME __init__32:01       MAKE_FUNCTION 116:05       STORE_NAME deposit32:02       MAKE_FUNCTION 216:06       STORE_NAME withdraw32:03       MAKE_FUNCTION 316:07       STORE_NAME transfer32:04       MAKE_FUNCTION 416:08       STORE_NAME check_balance51          LOAD_CONST_NONE 63          RETURN_VALUE children: ['__init__', 'deposit', 'withdraw', 'transfer', 'check_balance']
simple_name: __init__raw bytecode: 19 a3:01:0c:09:12:0a:0b:40:24:b1:b0:18:0a:b2:b0:18:0b:51:63prelude: (5, 0, 0, 3, 0, 1)args: ['self', 'owner_name', 'balance']line info: 40:24b1          LOAD_FAST 1 b0          LOAD_FAST 0 18:0a       STORE_ATTR owner_nameb2          LOAD_FAST 2 b0          LOAD_FAST 0 18:0b       STORE_ATTR balance51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: depositraw bytecode: 50 32:10:05:12:13:60:60:25:29:51:b1:80:d8:44:5a:b0:57:13:0b:b1:e5:5a:18:0b:12:14:23:00:14:0c:b1:b0:13:0b:36:02:34:01:59:42:47:12:14:23:01:34:01:59:51:63prelude: (7, 0, 0, 2, 0, 0)args: ['self', 'amount']line info: 60:60:25:29:51b1          LOAD_FAST 1 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:5a       POP_JUMP_IF_FALSE 26b0          LOAD_FAST 0 57          DUP_TOP 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 e5          BINARY_OP 14 __iadd__ 5a          ROT_TWO 18:0b       STORE_ATTR balance12:14       LOAD_GLOBAL print23:00       LOAD_CONST_OBJ 'Deposited ${}. New balance: ${}'14:0c       LOAD_METHOD formatb1          LOAD_FAST 1 b0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:01       LOAD_CONST_OBJ 'Invalid deposit amount.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: withdrawraw bytecode: 57 32:10:06:12:13:80:0d:2c:29:51:b1:80:d8:44:61:b0:13:0b:b1:db:44:5a:b0:57:13:0b:b1:e6:5a:18:0b:12:14:23:02:14:0c:b1:b0:13:0b:36:02:34:01:59:42:47:12:14:23:03:34:01:59:51:63prelude: (7, 0, 0, 2, 0, 0)args: ['self', 'amount']line info: 80:0d:2c:29:51b1          LOAD_FAST 1 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:61       POP_JUMP_IF_FALSE 33b0          LOAD_FAST 0 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 db          BINARY_OP 4 __ge__ 44:5a       POP_JUMP_IF_FALSE 26b0          LOAD_FAST 0 57          DUP_TOP 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 e6          BINARY_OP 15 __isub__ 5a          ROT_TWO 18:0b       STORE_ATTR balance12:14       LOAD_GLOBAL print23:02       LOAD_CONST_OBJ 'Withdrew ${}. New balance: ${}'14:0c       LOAD_METHOD formatb1          LOAD_FAST 1 b0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:03       LOAD_CONST_OBJ 'Invalid or insufficient funds for withdrawal.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: transferraw bytecode: 81 3b:18:07:12:15:13:80:14:2d:25:27:27:51:49:b0:13:0b:b2:db:44:73:b1:b0:de:d3:44:6d:b2:80:d8:44:5f:b0:14:06:b2:36:01:59:b1:14:05:b2:36:01:59:12:14:23:04:14:0c:b2:b1:13:0a:36:02:34:01:59:42:47:12:14:23:05:34:01:59:42:47:12:14:23:06:34:01:59:51:63prelude: (8, 0, 0, 3, 0, 0)args: ['self', 'recipient_wallet', 'amount']line info: 80:14:2d:25:27:27:51:49b0          LOAD_FAST 0 13:0b       LOAD_ATTR balanceb2          LOAD_FAST 2 db          BINARY_OP 4 __ge__ 44:73       POP_JUMP_IF_FALSE 51b1          LOAD_FAST 1 b0          LOAD_FAST 0 de          BINARY_OP 7 <is> d3          UNARY_OP 3 <not> 44:6d       POP_JUMP_IF_FALSE 45b2          LOAD_FAST 2 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:5f       POP_JUMP_IF_FALSE 31b0          LOAD_FAST 0 14:06       LOAD_METHOD withdrawb2          LOAD_FAST 2 36:01       CALL_METHOD 159          POP_TOP b1          LOAD_FAST 1 14:05       LOAD_METHOD depositb2          LOAD_FAST 2 36:01       CALL_METHOD 159          POP_TOP 12:14       LOAD_GLOBAL print23:04       LOAD_CONST_OBJ 'Transferred ${} to {}.'14:0c       LOAD_METHOD formatb2          LOAD_FAST 2 b1          LOAD_FAST 1 13:0a       LOAD_ATTR owner_name36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:05       LOAD_CONST_OBJ 'Invalid transfer amount.'34:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:06       LOAD_CONST_OBJ 'Insufficient funds or invalid recipient.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: check_balanceraw bytecode: 22 21:08:08:12:80:1f:12:14:23:07:14:0c:b0:13:0b:36:01:34:01:59:51:63prelude: (5, 0, 0, 1, 0, 0)args: ['self']line info: 80:1f12:14       LOAD_GLOBAL print23:07       LOAD_CONST_OBJ 'Current balance: ${}'14:0c       LOAD_METHOD formatb0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:01       CALL_METHOD 134:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/571554.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中霖教育:不是会计专业能参加24年的中级会计师考试吗?

经常有很多同学问&#xff1a;我不是会计专业的能报中级会计师考试吗? 先来看报名需要满足的必要条件&#xff1a; 1、大学专科学历&#xff0c;从事会计工作满5年。 2、大学本科学历或学士学位&#xff0c;从事会计工作满4年。 3、第二学士学位或研究生班毕业&#xff0c…

通过Jmeter准备压测数据-mysql示例

1、新建线程组 总共30万条数据 2、创建jdbc链接 创建jdbc连接配置 配置mysql连接 需要在jmeter安装的路径\apache-jmeter-5.6.3\lib\ext 目录下添加mysql 驱动 3、创建jdbc请求 jdbc链接名称需要与上一步中的保持一致&#xff0c;同时添加insert语句 例如 INSERT INTO test…

电子商务营销中大数据分析的应用|大数据分析在B2C中的应用案例【抖音/京东/淘宝商品数据采集API接口的应用】

文章围绕对大数据分析在电子商务营销中的应用开展&#xff0c;研究了什么是大数据分析和电子商务的营销&#xff0c;以及对于电子商务的营销与大数据分析的结合目前是一个什么样的趋势&#xff0c;分析了大数据分析在电子商务营销中的作用&#xff0c;希望能帮助到大家。抖音/京…

iOS App 上架指南及关键

引言 上架App Store是将iOS应用提交申请并上线的过程&#xff0c;旨在让应用在App Store上展示&#xff0c;吸引用户并获取流量。本文将介绍iOS上架的整体流程&#xff0c;并提供一些建议和注意事项。 一、iOS上架的整体流程 1. 申请开发者账号 首先&#xff0c;需要申请苹…

【免费】面向多微网网络结构设计的大规模二进制矩阵优化算法

目录 1 主要内容 节点故障网络拓扑变化示意 约束条件 目标函数 2 部分代码 3 结果一览 4 下载链接 1 主要内容 当前电力系统中微电网逐步成为发展的主力军&#xff0c;微网中包括分布式电源和负荷&#xff0c;单一的微电网是和外部电源进行连接&#xff0c;即保证用电的…

灰豚技术:数字人系统一定要源码部署,原因有三

数字人源码部署指的是将AI数字人系统源代码进行安装和配置的过程。这通常涉及准备本地服务器或云服务器、准备域名并进行网站备案&#xff0c;然后将源码部署到服务器上。完成部署后&#xff0c;用户就可以开始运营自己的数字人平台&#xff0c;进行数字人的本地化部署&#xf…

NO11 蓝桥杯单片机之DS18B20数字温度计

DS18B20数字温度计这个模块和以往单片机学习的模块可能不同&#xff0c;这里还要知道其头文件&#xff08;.h&#xff09;和.c文件代码的理解。 具体这个温度计是怎么实现检测温度的&#xff0c;呃呃呃呃呃这可能就要去查阅专业资料&#xff0c;涉及的知识体系应该很庞大&…

LeetCode刷题---查询近30天活跃用户数

1.给出满足的条件&#xff0c;截止至2019-07-27的近30天 activity_date BETWEEN DATE_ADD(2019-07-27,INTERVAL -29 day) and 2019-07-27这里使用了Between and 函数和 Date_add函数 2.按照日期分组&#xff0c;统计活跃用户个数 select activity_date day,count(distinct(us…

Android Studio 无法下载 gradle-7.3.3-bin.zip

下载新的Android Studio&#xff0c;然后创建新的工程时&#xff0c;出现报错&#xff1a;Could not install Gradle distribution from https://services.gradle.org/distributions/gradle-7.3.3-bin.zip 或者超时&#xff0c;我们可以复制&#xff1a;https://services.grad…

笔记本作为其他主机显示屏(HDMI采集器)

前言&#xff1a; 我打算打笔记本作为显示屏来用&#xff0c;连上工控机&#xff0c;这不是贼方便吗 操作&#xff1a; 一、必需品 HDMI采集器一个 可以去绿联买一个&#xff0c;便宜的就行&#xff0c;我的大概就长这样 win10下载 PotPlayer 软件 下载链接&#xff1a;h…

基于云计算的前端资源管理系统的设计与实现

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 随着互联网的快速发展&#xff0c;前端资源管理成为了一个重要的课题。本文旨在设计并实…

BRICK POP展示了有趣的链上游戏玩法与奖励机制

新游戏BRICK POP将Sui区块链技术与低Gas费用&#xff0c;以及其在Web3游戏开发方面的专业知识无缝结合。通过充分利用Sui和ONBUFF的INNO平台优势&#xff0c;BRICK POP为玩家提供了一个融合了前沿技术和引人入胜游戏的沉浸式游戏体验。BRICK POP游戏设计为实时交易和高用户参与…