好的,我可以使用以下内容在NSArrays上存储块:
NSArray *myArray = @[[myBlock1 copy], [myBlock2 copy]];
稍后运行该代码,例如:
myBlockType runBlock = myArray[0];
runBlock(); // run baby, run
与此相当的C怎么样?这可能吗?
答案 0 :(得分:2)
这有效:
typedef void (^MyBlockType)(void);
MyBlockType blocks[100];
for(int i = 0; i < 100; i++) {
MyBlockType block= ^{printf("Run!");};
blocks[i] = block;
}
MyBlockType thisBlock = blocks[0];
thisBlock();
答案 1 :(得分:0)
如果操作系统允许您这样做,您可以将数组的地址分配给函数指针,并使用该指针的名称调用数组中的代码。
typedef void (*fx_t)(void);
int main(void) {
fx_t udf;
unsigned char code[1000] = "<<machine code instructions>>";
udf = code; /* UB: assignment of object pointer to non-object pointer */
/* illegal assignment according to the Standard */
udf();
return 0;
}
根据评论中的请求,这是一个完整的示例,适用于我的计算机(amd64上的FreeBSD 9.2)
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
typedef int (*fx_t)(void);
int main(void) {
int a = -1;
fx_t udf;
unsigned char code[1000] = "\xb8\x2a\x00\x00\x00" // mov $0x2a,%eax
"\xc3"; // retq
void *codeaddr = code;
size_t length = 4096; /* size of a page */
if (mprotect(codeaddr, length, PROT_READ | PROT_WRITE | PROT_EXEC)) {
perror("mprotect");
exit(EXIT_FAILURE);
}
udf = (void*)code;
a = udf(); // call the code in the `code` string
printf("a is now %d.\n", a); // expect 42, changed by the code in `code`
code[1] = 24; // w00t! self changing code
a = udf();
printf("a is now %d.\n", a); // expect 24
return 0;
}
为了得到code
的字节,我编译了一个非常简单的int fortytwo(void) { return 42; }
到目标文件然后objdump -d
它并尝试了看似相关的字节(我不知道汇编)语言)
0000000000000000 <fortytwo>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: b8 2a 00 00 00 mov $0x2a,%eax 9: c9 leaveq a: c3 retq b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)