我在C中有以下代码:
int addInt(int n, int m) {
return n + m;
}
int (*functionPtr)(int, int);
functionPtr = &addInt;
functionPtr 是一个函数指针,它指向函数 addInt 的特定地址。我想改变它的1位值,但我无法弄清楚如何。
让 functionPtr 指向最后一个语句后的 0xABC0 (假设为16位地址)。我想将其值更改为 0xABC1 。我试图将值与0x1进行OR运算,但我猜操作数转换有问题:
functionPtr = &addInt | 0x00000001; // addresses are of 32 bits
我知道弄乱指针是有风险的,但我必须更改地址的LSB才能进入ARM Cortex-M4 MCU的Thumb状态。
答案 0 :(得分:1)
要通过算术运算修改指针的值,您需要将其转换为整数类型,执行操作,然后将其转换回来。 C没有定义将函数指针转换为除另一个函数指针以外的任何函数的行为,但是,没有定义的方法来执行此操作。
你可以写下这个:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://www.myexample.com/download/iOS/myenterpriseapp.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.swatchdog.enterprise</string>
<key>bundle-version</key>
<string>1.0.34</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>myApp for iPad II and above</string>
<key>title</key>
<string>SwatchDog</string>
</dict>
</dict>
</array>
</dict>
</plist>
您正在寻找的行为是更合理的结果之一,但同样,两个演员的行为都是 undefined 。因此,通过修改的指针执行函数调用所期望的行为 - 如果你的程序甚至可以达到那么远 - 也是未定义的。即使接受代码也不需要编译器。
答案 1 :(得分:0)
可能这不是一个坏主意,但如果你真的需要这个,那么以下可以做到这一点:
functionPtr = &addInt;
*(int*)&functionPtr |= 1;
但请注意,这不是便携式的,并且可能在您的环境中起作用或根本不起作用。
答案 2 :(得分:0)
许多人提到你的方法很危险,但在某些情况下,这是一个真正的问题,我不止一次遇到过。我怀疑,目前你的代码使用BL
指令(分支和链接),它不会改变CPU的模式到拇指,为了根据你的函数指针执行从ARM到拇指的调用,添加编译代码时gcc的-mthumb-interwork
标志:
生成支持ARM和Thumb之间调用的代码 指令集。没有这个选项,在v5之前的架构上, 在一个程序中无法可靠地使用两个指令集。该 默认是-mno-thumb-interwork,因为稍微大一点的代码 指定-mthumb-interwork时生成。在AAPCS配置中 这个选项毫无意义。
答案 3 :(得分:-2)
函数指针格式取决于架构和实现。
例如,在Itanium上,function pointers point to a read only data structure包含函数所属模块的相应全局指针,以及实际的函数指针。