提问人:AsheofMidgard 提问时间:10/28/2023 更新时间:10/29/2023 访问量:60
为什么这两个 C 函数在 Python 中使用 ctypes lib 调用时会生成不同的返回值?
Why these two C functions generate different return values when called in Python using ctypes lib?
问:
在这里,我实现了两个 C 函数:
void testFunc1(int **a)
{
int temp[4] = {1,2,3,4};
*a = temp;
}
void testFunc2(int **a, int b)
{
int temp[4] = {1,2,3,4};
*a = temp;
}
如图所示,这两个函数应将 *a 的值更改为 temp[0] 的地址,因此可以通过指针 a 返回数组 temp。 b 不是使用的参数,我把它放在 testFunc2 中,因为我发现它可能会引起一些令人困惑的结果。然后我把这个代码文件编译成“./test.dll”。
但是,当我通过 ctypes lib 在 python 中调用这两个函数时:
from ctypes import *
testdll = CDLL("./test.dll")
testdll.testFunc1.argtypes = (POINTER(POINTER(c_int)),)
testdll.testFunc2.argtypes = (POINTER(POINTER(c_int)), c_int)
print("Test func 1:")
a = pointer(pointer(c_int(-1)))
print(" Before calling func:")
print(f" a={a}")
print(f" a.contents={a.contents}")
print(f" a.contents.contents={a.contents.contents}")
testdll.testFunc1(a)
print(" After calling func:")
print(f" a={a}")
print(f" a.contents={a.contents}")
print(f" a.contents.contents={a.contents.contents}")
print("Test func 2:")
a = pointer(pointer(c_int(-1)))
print(" Before calling func:")
print(f" a={a}")
print(f" a.contents={a.contents}")
print(f" a.contents.contents={a.contents.contents}")
testdll.testFunc2(a, c_int(4))
print(" After calling func:")
print(f" a={a}")
print(f" a.contents={a.contents}")
print(f" a.contents.contents={a.contents.contents}")
印刷品是这样的:
Test func 1:
Before calling func:
a=<__main__.LP_LP_c_long object at 0x00000263EC1B2CD0>
a.contents=<__main__.LP_c_long object at 0x00000263EC1B2D50>
a.contents.contents=c_long(-1)
After calling func:
a=<__main__.LP_LP_c_long object at 0x00000263EC1B2CD0>
a.contents=<__main__.LP_c_long object at 0x00000263EC1B2DD0>
a.contents.contents=c_long(1)
Test func 2:
Before calling func:
a=<__main__.LP_LP_c_long object at 0x00000263EC1B2E50>
a.contents=<__main__.LP_c_long object at 0x00000263EC1B2CD0>
a.contents.contents=c_long(-1)
After calling func:
a=<__main__.LP_LP_c_long object at 0x00000263EC1B2E50>
a.contents=<__main__.LP_c_long object at 0x00000263EC1B2BD0>
a.contents.contents=c_long(0)
它表明 testFunc2 似乎对值为“0”的整数表示 *。这是一个令人困惑的结果,因为 testFunc2 只在其参数列表中添加一个未使用的参数 b。为什么与 testFunc1 相比,它会生成不同的结果?
请参阅问题部分。我在那里提到了我的实验。
答:
3赞
0___________
10/28/2023
#1
当您分配对自动存储持续时间数组的引用(并因此在 Python 代码中取消引用它)时,这两个函数都会调用未定义的行为,这些数组在函数返回时将停止存在。
为什么这两个 C 函数在调用时会生成不同的返回值 在 Python 中使用 ctypes lib?
因为这是一种未定义的行为,你不能假设任何行为。
您需要使它们静态或动态分配它们:
void testFunc1(int **a)
{
static int temp[4] = {1,2,3,4};
*a = temp;
}
void testFunc1(int **a)
{
int *temp = malloc(4 * sizeof(*temp));
memcpy(temp, (int[]){1,2,3,4}, 4 * sizeof(*temp));
*a = temp;
}
评论
0赞
chux - Reinstate Monica
10/29/2023
看起来你玩得很开心。memcpy(temp, (int[]){1,2,3,4}, 4 * sizeof(*temp));
0赞
AsheofMidgard
10/29/2023
非常感谢!简直不敢相信我忘记了这整件事。我想这些天我一定写了太多的 Python 而写的 C 太少了。
评论
*a
temp