struct Block_byref_2 *copy2 = (struct Block_byref_2 *)(copy+1); copy2->byref_keep = src2- >byref_keep; copy2->byref_destroy = src2->byref_destroy; if (src->flags & BLOCK_BYREF_LAYOUT_EXTENDED 3,在源码中,判断BLOCK_BYREF_HAS_COPY_DISPOSE符合之后还会进行byref_keep和byref_destroy的迁移: ? byref_keep和byref_destroy是定义在Block_byref_2结构体中的: ? byref_keep对应的就是__Block_byref_id_object_copy_131。
/* VT_BYREF|VT_I8 */ FLOAT * pfltVal; /* VT_BYREF|VT_R4 */ /* VT_BYREF|VT_DATE */ BSTR * pbstrVal; /* VT_BYREF|VT_BSTR */ ppdispVal; /* VT_BYREF|VT_DISPATCH */ SAFEARRAY ** pparray; /* VT_BYREF| PVOID byref; /* Generic ByRef */ CHAR cVal; /* VT_BYREF|VT_UI4 */ ULONGLONG * pullVal; /* VT_BYREF|VT_UI8 */
__Block_byref_age_0赋值 __isa指针 :__Block_byref_age_0中也有isa指针也就是说__Block_byref_age_0本质也一个对象。 __flags :0 __size :sizeof(__Block_byref_age_0)即__Block_byref_age_0所占用的内存空间。 那么同样的当block内部捕获__block修饰的对象类型的变量时,__Block_byref_person_0结构体内部也会自动添加__Block_byref_id_object_copy和__Block_byref_id_object_dispose __Block_byref_age_0结构体,堆中__Block_byref_age_0结构体内的__forwarding指针依然指向自己。 _0结构体声明 __attribute__((__blocks__(byref))) __Block_byref_person_0 person = { (void*)0, (__Block_byref_person
__isa指针 :__Block_byref_age_0中也有isa指针也就是说__Block_byref_age_0本质也一个对象。 __flags :0 __size :sizeof(__Block_byref_age_0),即__Block_byref_age_0所占用的内存空间。 接着将__Block_byref_age_0结构体age存入__main_block_impl_0结构体中,并赋值给__Block_byref_age_0 *age; ? 那么同样的当block内部捕获__block修饰的对象类型的变量时,__Block_byref_person_0结构体内部也会自动添加__Block_byref_id_object_copy和__Block_byref_id_object_dispose __Block_byref_age_0结构体,堆中__Block_byref_age_0结构体内的__forwarding指针依然指向自己。
Block_layout 3.2 __block修饰后Block_byref模板 struct Block_byref { void *isa; struct Block_byref * 和 byref_destroy 函数 - 来处理里面持有对象的保持和销毁 struct Block_byref_2 { // requires BLOCK_BYREF_HAS_COPY_DISPOSE 内存拷贝 以及常规处理 static struct Block_byref *_Block_byref_copy(const void *arg) { struct Block_byref * _2 *)(copy+1); copy2->byref_keep = src2->byref_keep; copy2->byref_destroy = src2 Block_byref_3 *src3 = (struct Block_byref_3 *)(src2+1); struct Block_byref_3 *copy3 =
_0 a ={ void* 0, (__Block_byref_a_a *)&a, 0, sizeof(__Block_byref_a_0), 10}; __ main_block_impl_0(func_0,&DATA,&a,570425344); } struct __Block_byref_a_0{ void *isa; __Block_byref_a *a; __main_block_impl_0(*fp,*desc,__Block_byref_a_0 *_a,flags ):a(a->__forwarding){ impl.isa 修饰的变量 *dest = _Block_byref_copy(object) QQ截图20201215071532.png } } _block_byref_copy _block_byref_copy(*arg){ struct Block_byref *src = (struct Block_byref *) arg;三层拷贝 struct Block_byref
))) __Block_byref_person_0 person = { (void*)0, (__Block_byref_person_0 *)&person , 33554432, sizeof(__Block_byref_person_0), __Block_byref_id_object_copy _0中 struct __Block_byref_person_0 { void *__isa; // isa __Block_byref_person_0 *__forwarding; //指向自己的指针 当block从栈copy到堆中 则指向堆中block的地址 int __flags; // 标记 int __size; // 大小 void (*__Block_byref_id_object_copy )(void*, void*); // 当block被拷贝到堆中执行此方法 void (*__Block_byref_id_object_dispose)(void*); // 当block释放 执行这个方法
对应于源码中的 __block int val = 1; __attribute__((__blocks__(byref))) __Block_byref_val_0 val = {(void*)0,( 结构体__Block_byref_val_0 __Block_byref_val_0也是一个结构体,该结构体包含如下5个成员变量: void *__isa; __Block_byref_val_0 *_ ))) __Block_byref_val_0 val = {(void*)0,(__Block_byref_val_0 *)&val, 0, sizeof(__Block_byref_val_0), ))) __Block_byref_val_0 val = {(void*)0,(__Block_byref_val_0 *)&val, 0, sizeof(__Block_byref_val_0), __cself->val->__forwarding是结构体__Block_byref_val_0中__Block_byref_val_0类型的成员变量__forwarding,__Block_byref_val
)))__Block_byref_a_0 a = { (void*)0,(__Block_byref_a_0*)&a, 0, sizeof(__Block_byref_a_0)}; )))__Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0)}; ; */ int size; void(*byref_keep)(struct Block_byref *dst, structBlock_byref *src); )))__Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 33554432, sizeof(__Block_byref_a_0), __Block_byref_id_object_copy block this is wrong XXX copy->byref_keep =src->byref_keep; copy->byref_destroy =src->byref_destroy
我们可以先来看看test.cpp的部分实现: struct __Block_byref_b_0 { void *__isa; __Block_byref_b_0 *__forwarding; int __flags; int __size; int b; }; struct __Block_byref_blockStr_1 { void *__isa; __Block_byref_blockStr ))) __Block_byref_b_0 b = {(void*)0,(__Block_byref_b_0 *)&b, 0, sizeof(__Block_byref_b_0), 20}; NSString ))) __Block_byref_blockStr_1 blockStr = {(void*)0,(__Block_byref_blockStr_1 *)&blockStr, 33554432, sizeof (__Block_byref_blockStr_1), __Block_byref_id_object_copy_131, __Block_byref_id_object_dispose_131, str
lpSearchCondition As Long, _ ByVal dwSearchCondition As Long, _ ByRef lpGroupId ByRef lpReserved As Long) As Long Private Declare Function DeleteUrlCacheGroup Lib "wininet.dll Alias "FindFirstUrlCacheEntryA" ( _ ByVal lpszUrlSearchPattern As String, _ ByRef lpFirstCacheEntryInfo As INTERNET_CACHE_ENTRY_INFO, _ ByRef lpdwFirstCacheEntryInfoBufferSize lpNextCacheEntryInfo As INTERNET_CACHE_ENTRY_INFO, _ ByRef lpdwNextCacheEntryInfoBufferSize
… short * piVal; // VT_BYREF|VT_I2. long * plVal; // VT_BYREF|VT_I4. float * pfltVal; // VT_BYREF|VT_R4. double * pdblVal; // VT_BYREF|VT_R8. DATE * pdate; // VT_BYREF|VT_DATE. BSTR * pbstrVal; // VT_BYREF|VT_BSTR. }; }; 显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型
我们来转换下源码,分析一下: struct __Block_byref_a_0 { void *__isa; __Block_byref_a_0 *__forwarding; int ))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 10}; _ _Block_byref_b_1 b = {(void*)0,(__Block_byref_b_1 *)&b, 0, sizeof(__Block_byref_b_1), 20}; void __Block_byref_a_0、__Block_byref_b_1 类型的结构体声明如下: struct __Block_byref_a_0 { void *__isa; __Block_byref_a (__Block_byref_a_0), 10 }; __Block_byref_b_1 b = { 0, &b, 0, sizeof(__Block_byref_b
__main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0* Desc; __Block_byref_val_ ))) __Block_byref_val_0 val = {(void*)0,(__Block_byref_val_0 *)&val, 0, sizeof(__Block_byref_val_0), 其实结构体__Block_byref_val_0产生的实例就是我们使用__block修饰过的变量。 struct __Block_byref_val_0 { void *__isa; __Block_byref_val_0 *__forwarding; int __flags; int __size; 我们从上述被转化的代码中可以看出 Block 本身也一样被转换成了__main_block_impl_0结构体实例,该实例持有__Block_byref_val_0结构体实例的指针。
_0 { void *__isa; __Block_byref_age_0 *__forwarding; int __flags; int __size; NSUInteger age; }; _0 *age; // by ref __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_age __main_block_impl_0*src) {_Block_object_assign((void*)&dst->age, (void*)src->age, 8/*BLOCK_FIELD_IS_BYREF /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; __attribute__((__blocks__(byref ))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0),
编译器会将 __block 修饰的变量包装成一个__Block_byref_age_0对象; 以上age = 20;的赋值过程为:通过 block 结构体里的(__Block_byref_age_0)类型的 age 指针,找到__Block_byref_age_0结构体的内存(即被 __block 包装成对象的内存),把__Block_byref_age_0结构体里的 age 变量的值改为20。 struct __Block_byref_age_0 { void *__isa; __Block_byref_age_0 *__forwarding; int __flags; ))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), void (*__Block_byref_id_object_copy)(void*, void*); // copy void (*__Block_byref_id_object_dispose
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy) blobOut = DATA_BLOB() if CryptProtectData(byref (blobIn), u"python_data", byref(blobEntropy), None, None, CRYPTPROTECT_UI_FORBIDDEN blobEntropy = DATA_BLOB(len(entropy), bufferEntropy) blobOut = DATA_BLOB() if CryptUnprotectData(byref (blobIn), None, byref(blobEntropy), None, None, CRYPTPROTECT_UI_FORBIDDEN , byref(blobOut)): return getData(blobOut) else: return ""7、定义函数来加密和解密数据:def cryptData
char v20[4]; // [sp+10h] [bp-58h] BYREF char v21[4]; // [sp+14h] [bp-54h] BYREF char v22[4]; / ] BYREF char v25[4]; // [sp+24h] [bp-44h] BYREF char v26[4]; // [sp+28h] [bp-40h] BYREF char v27 [4]; // [sp+2Ch] [bp-3Ch] BYREF char v28[4]; // [sp+30h] [bp-38h] BYREF char v29[4]; // [sp+34h] [bp-34h] BYREF char v30[4]; // [sp+38h] [bp-30h] BYREF char v31[4]; // [sp+3Ch] [bp-2Ch] BYREF char v32[8]; // [sp+40h] [bp-28h] BYREF int v33; // [sp+48h] [bp-20h] BYREF char v34; // [sp+4Ch]
_0 { void *__isa; __Block_byref_block_i_0 *__forwarding; int __flags; int __size; int block_i; } _0 *block_i; // by ref __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_block_i main_block_impl_0*src) {_Block_object_assign((void*)&dst->block_i, (void*)src->block_i, 8/*BLOCK_FIELD_IS_BYREF ))) __Block_byref_block_i_0 block_i = {(void*)0,(__Block_byref_block_i_0 *)&block_i, 0, sizeof(__Block_byref_block_i 0; } 可与发现,大概多了三个部分 当block从栈上被copy到堆上时,会调用__main_block_copy_0将__block类型的成员变量i从栈上复制到堆上,同时,栈上的__Block_byref_i
压缩数据块使用2个byte存储了没有压缩过的数据的长度LEN,再用2个byte记录了LEN的补码NLEN,根据这个,解压代码如下: Private Function InflateNoCompression(ByRef cpByte() As Byte, ByRef uncpByte() As Byte, ByRef bitIndex As Long, ByRef pUncp As Long) As Long