/2 반환 값 오류의 이유는 무엇입니까? /
지난 글에서 우리 모두는 사진 한 장을 잊어버린 것 같았습니다.
위에서 보면 GoInt가 실제로 GoInt64이고 GoInt64의 유형이 long long 유형이라는 것을 알 수 있습니다. ? ?
실제로 Python에서 .so 파일을 호출할 때 <code style="font-family: var(--monospace);vertical-align: initial;border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;"><span style="font-size: 18px;">ctypes</span>
ctypes 모듈, 여기에는 해당 테이블이 있습니다.
/… 根据上述表格我们可以发现,在C中的long long类型对应的ctype类型是c_longlong。 所以我们需要在Python将.so中的返回值改一下,不能使用系统默认的了。代码如下: 再次执行: 可以看到,这次Python执行的结果和Go执行结果就一个样了。继续,换个数字试试看。 基本可以确定,这次是没问题了。 /4 如果返回的是字符串呢?/ Go代码 下面一起来理解.h文件。编译之后打开.h文件如下图所示: 可以看到,在extern的函数成了两个,但是他的返回值是GoString,继续找。 可以发现,其实GoString就是_GoString_,继续找。 这次是一个结构体,里面其实是两个值,不在是单独的long long了,那Python中的继承类也要改一下了。 下面基本同上。 完整代码如下: 结果: 可以看到,调用Go代码成功的拿到了正确的字符串返回值,如果没有 .restype = StrPointer拿到的会是什么呢?拿到会和原来的一样,一堆数字,这里就不举栗子了。 /5 小结/ 至此,基本上在Python调用Go代码上的大坑都解决了,最复杂的是返回字符串类型,查了很多相关资料才解决。 关于返回其他类型的Python的class怎么写,我相信已经难为不到你们了,最复杂的都解决了,最简单的还不会吗?(除字符串类型以外其他_fields_都是一个字段的) 我相信各位小伙伴学习能力还是很强的,人生苦短,Python当歌,加油,奥利给!
ctypes 유형
C 유형
Python 유형
c_bool
_Bool
부울 (1)
c_char
char
1자 바이트 object
c_wchar
wchar_t
1자 string
c_byte
char
int
c_ubyte
부호 없는 문자
int
c_short
short
int
c_ushort
int
c_int
int
int
c_uint
unsigned int
int
c_long long
int
c_ulong
unsigned long
int
c_longlong
__int64 또는 long long
int
c_ulonglong
unsigned __int64 또는 unsigned long long
int
c_size_t
size_t
int
c_ssize_t
ssize_t y_ssize_t
int
c_float
float
float
c_double
double
float
c_longdouble
float
c_char_p
char * (NUL 종료됨 )
bytes 객체 또는 None
c_wchar_p
wchar_t * (NUL 종료)
string 또는 None
c_void_p
void *
int 또는 None
from ctypes import *
import time
class StructPointer(Structure):
# 根据查表,C中的long long,对应的ctypes 是 c_longlong
# _fields_必须是[](列表)类型,里面写对应的类型,固定格式
_fields_ = [("p", c_longlong,),]
if __name__ == '__main__':
beginTime = time.time()
s = CDLL("s1.so") # 加载s1.so文件
s.run.restype = StructPointer # 声明.so的run函数返回值类型,固定格式
result = s.run(100000000) # 调用Go生成的.so文件里面的run函数
print("result:", result.p)# 此处需要调用.p来获取值,和 _fields_对应
endTime = time.time()
print("耗时:", endTime - beginTime)
package main
import (
"C" //C必须导入
"fmt"
)
//export run
func run(n int) int{
/*
必须要export 函数名
//是注释的意思,相当于Python中的 #
我也是第一次见注释还有作用
*/
sum := 0
for i := 0; i < n; i++ {
sum += i
}
fmt.Println("我是Go代码,我跑完了,我的结果是:",sum)
return sum
}
//export speak
func speak(n int) string{
return "OMG 996好累呀,难得休息一天,好好休息"
}
func main() {
//main函数中什么都不要写,和包名main要对应
}
from ctypes import *
import time
class StructPointer(Structure):
# 根据查表,C中的long long,对应的ctypes 是 c_longlong
# _fields_必须是[](列表)类型,里面写对应的类型,固定格式
_fields_ = [("p", c_longlong,),]
class StrPointer(Structure):
# typedef struct { const char *p; ptrdiff_t n; } _GoString_;
# ptrdiff_t == long long
_fields_ = [("p", c_char_p), ("n", c_longlong)]
if __name__ == '__main__':
beginTime = time.time()
s = CDLL("s1.so") # 加载s1.so文件
s.run.restype = StructPointer # 声明.so的run函数返回值类型,固定格式
result = s.run(100000798) # 调用Go生成的.so文件里面的run函数
print("result:", result.p)# 此处需要调用.p来获取值,和 _fields_对应
s.speak.restype = StrPointer
speakStr = s.speak()
# 返回的是字节类型,需要转字符串,返回的内容在.p中,.n是切的长度,后面会跟一些介绍,不需要
speakStr = str(speakStr.p[:speakStr.n], encoding="utf-8")
print("speak:",speakStr)
endTime = time.time()
print("耗时:", endTime - beginTime)
위 내용은 [고급] Python+Go - 컴퓨팅 성능을 향상시키는 또 다른 방법을 찾아보자의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!