我在動態庫(.so)上設計了一個帶有浮點引數的函式。但是該函式無法獲得我傳遞的正確值。
代碼示例 1
mylib.c
void pass_float_to_lib(float a_float)
{
printf("Lib get %f\n", a_float);
}
主檔案
int main(void)
{
float my_float = 1.3;
printf("Pass %f\n", my_float);
pass_float_to_lib(my_float);
return 0;
}
輸出:
Pass 1.300000
Lib get -2.000000
為什么我將 float 1.3 傳遞給庫,但它會得到 -2.000000
因此,我將浮點值傳遞給 main.c 旁邊的另一個函式,并添加一些除錯訊息。我發現堆疊之間(char guard_a 和 gyard_b 之間)的浮點值不是我通過的。
代碼示例 2
主檔案:
void pass_float(char guard_a, float a_float, char guard_b)
{
printf("The float is %f\n", a_float);
printf("address:\n"
"grard_a %p\n"
"a_float %p\n"
"guard_b %p\n",
&guard_a, &a_float, &guard_b);
char *p_stack = &guard_b;
while (p_stack <= &guard_a) {
printf("Addr %p: Byte %x \n", p_stack, *p_stack & 0xff);
p_stack ;
}
}
int main(void)
{
float my_float = 1.3;
printf("Test A\n");
pass_float('a', my_float, 'b');
pass_float_to_lib('a', my_float, 'b');
printf("Test B\n");
char *p = (char *) &my_float;
*p = 0x11;
*p = 0x22;
*p = 0x33;
*p = 0x44;
pass_float('a', my_float, 'b');
pass_float_to_lib('a', my_float, 'b');
return 0;
}
mylib.c
void pass_float_to_lib(char guard_a, float a_float, char guard_b)
{
printf("The float is %f\n", a_float);
printf("address:\n"
"grard_a %p\n"
"a_float %p\n"
"guard_b %p\n",
&guard_a, &a_float, &guard_b);
char *p_stack = &guard_b;
while (p_stack <= &guard_a) {
printf("Addr %p: Byte %x \n", p_stack, *p_stack & 0xff);
p_stack ;
}
}
輸出:
Test A
The float is 1.300000
address:
grard_a 0x7ffc72d987ec
a_float 0x7ffc72d987e8
guard_b 0x7ffc72d987e4
Addr 0x7ffc72d987e4: Byte 62
Addr 0x7ffc72d987e5: Byte 0
Addr 0x7ffc72d987e6: Byte 0
Addr 0x7ffc72d987e7: Byte 0
Addr 0x7ffc72d987e8: Byte 66
Addr 0x7ffc72d987e9: Byte 66
Addr 0x7ffc72d987ea: Byte a6
Addr 0x7ffc72d987eb: Byte 3f
Addr 0x7ffc72d987ec: Byte 61
The float is -2.000000
address:
grard_a 0x7ffc72d987ec
a_float 0x7ffc72d987e8
guard_b 0x7ffc72d987e4
Addr 0x7ffc72d987e4: Byte 62
Addr 0x7ffc72d987e5: Byte 0
Addr 0x7ffc72d987e6: Byte 0
Addr 0x7ffc72d987e7: Byte 0
Addr 0x7ffc72d987e8: Byte 0
Addr 0x7ffc72d987e9: Byte 0
Addr 0x7ffc72d987ea: Byte 0
Addr 0x7ffc72d987eb: Byte c0
Addr 0x7ffc72d987ec: Byte 61
Test B
The float is 716.532288
address:
grard_a 0x7ffc72d987ec
a_float 0x7ffc72d987e8
guard_b 0x7ffc72d987e4
Addr 0x7ffc72d987e4: Byte 62
Addr 0x7ffc72d987e5: Byte 0
Addr 0x7ffc72d987e6: Byte 0
Addr 0x7ffc72d987e7: Byte 0
Addr 0x7ffc72d987e8: Byte 11
Addr 0x7ffc72d987e9: Byte 22
Addr 0x7ffc72d987ea: Byte 33
Addr 0x7ffc72d987eb: Byte 44
Addr 0x7ffc72d987ec: Byte 61
The float is 0.000000
address:
grard_a 0x7ffc72d987ec
a_float 0x7ffc72d987e8
guard_b 0x7ffc72d987e4
Addr 0x7ffc72d987e4: Byte 62
Addr 0x7ffc72d987e5: Byte 0
Addr 0x7ffc72d987e6: Byte 0
Addr 0x7ffc72d987e7: Byte 0
Addr 0x7ffc72d987e8: Byte 0
Addr 0x7ffc72d987e9: Byte 0
Addr 0x7ffc72d987ea: Byte 0
Addr 0x7ffc72d987eb: Byte 20
Addr 0x7ffc72d987ec: Byte 61
以下命令是編譯代碼的步驟。
編譯動態庫:
gcc -fPIC -O -c mylib.c -o mylib.o
gcc -shared mylib.o -o libmylib.so
編譯 main 并執行它:
- gcc -O -c main.c
- gcc main.o -L. -lmylib
- LD_LIBRARY_PATH=。./a.out
uj5u.com熱心網友回復:
在呼叫之前宣告例程。如果沒有宣告,編譯器會將函式視為隱式宣告,執行默認引數提升,并將float轉換為double。這會導致資料被錯誤地傳遞和解釋。
獲取引數的地址并在那里列印記憶體是沒有用的。引數通常在暫存器中傳遞。然后,當您獲取引數的地址時,編譯器將其復制到記憶體中,只是為了獲得地址。編譯器為此用于各種引數的地址不一定與這些引數在暫存器中的顯示方式有任何關系。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/348679.html
上一篇:free()后出現分段錯誤
下一篇:運算子“<<=”:是什么意思?
