네가해야하는 이유는 그것이 ctypes 'guess 때문인 것입니다. int test_i(int i)
을 int test_i(char i)
으로 바꾸면 스택 손상이 발생합니다. 파이썬 측은 4 또는 8 바이트 기능을 제공하고 C 측은 1 바이트 만 읽으므로 스택 손상이 발생합니다. 플랫폼에 따라 약간의 시간 동안 주목을받지 못하거나 점차 스택을 먹거나 충돌이 발생하거나 아무 일도 일어나지 않을 것입니다. 어쨌든이 코드 스타일은 냄새가납니다.
ctypes
은 파이썬 유형 시스템이 C보다 훨씬 간단하기 때문에 많은 경우 도움이되지 않습니다. 예를 들어, Python 측은 1 바이트, 2 바이트, 4 바이트 또는 8 바이트 정수를 전달하는지 알아낼 수있는 방법이 없습니다. 파이썬 정수는 크기가 없기 때문입니다. 파이썬에는 배정도 부동 소수점 만 있고 C면에는 단일 및 반수가 있으며 플랫폼 별 정밀도가있을 수 있습니다. 문자열과 바이트는 파이썬 측에서만 적절히 구분되며, C 측에서는 유니 코드로 작업하는 것이 일반적으로 엉망입니다. wchar_t[]
또는 char[]
을 사용할 지 여부는 명확하지 않습니다. 문자열을 어떻게 종료 하시겠습니까?이 작업이 필요합니까, 그리고 어떻게 파이썬 문자열 불변성으로 돌아가고 싶습니까? argtypes
이 없으면 구조와 배열을 쉽게 전달할 수 없습니다.
는 또한,도 restype
를 지정하는 것을 잊지 마세요 : 기본적 ctypes
으로
libc.test_f.restype = c_int
는 모든 기능이 플랫폼에 대해 무엇이든, int
을 반환 가정합니다. 호출 규칙에 따라 CPU 레지스터가 결과를 반환하는 데 사용할 수 있습니다.이 경우 레지스터가 읽혔는지 여부에 차이가 없으므로 해를 끼치 지 않습니다. 다른 경우 스택에 의해 결과가 전달되고 스택이 너무 많이 소모되면 스택 손상이 발생하지 않으므로 function RET
은 잘못된 주소를 표시하고 SIGSEGV에 대한 인사를하는 것이 가장 좋습니다. 최악의 경우 해커는 애플리케이션을 사용하여 속임수를 쓰게됩니다.
일반적으로 argtypes
과 restype
은 코드가 예측할 수없는 방식으로 분리되는 것을 방지하고 모든 것이 C와 Python에서 너무 많이 다르기 때문에 필요합니다. 그렇지 않다면 아무도 선 (Zen)과 배터리 (battery)로 인해 이들을 사용하도록 강요하지 않을 것입니다.