import base64
import ctypes
import json
import Crypto
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
class WxWork:
CORP_ID = ''
PRI_KEY = ''
CHAT_SECRET = ''
@classmethod
def sync_msg(cls):
dll = ctypes.cdll.LoadLibrary(os.getcwd() + "/libWeWorkFinanceSdk_C.so") # 真实libWeWorkFinanceSdk_C位置
new_sdk = dll.NewSdk()
result = dll.Init(new_sdk, cls.CORP_ID.encode(), cls.CHAT_SECRET.encode())
if result != 0:
return
private_key = RSA.import_key(cls.PRI_KEY)
cipher = Crypto.Cipher.PKCS1_v1_5.new(private_key)
seq = 0
while True:
s = dll.NewSlice()
dll.GetChatData(new_sdk, seq, 1000, '', '', 5, ctypes.c_long(s))
data = dll.GetContentFromSlice(s)
data = ctypes.string_at(data, -1).decode("utf-8")
dll.FreeSlice(s)
data = json.loads(data).get('chatdata')
if not data:
break
seq = data[-1].get('seq')
for msg in data:
encrypt_key = cipher.decrypt(base64.b64decode(msg.get('encrypt_random_key')), "ERROR")
ss = dll.NewSlice()
dll.DecryptData(encrypt_key, msg.get('encrypt_chat_msg').encode(), ctypes.c_long(ss))
result = dll.GetContentFromSlice(ss)
result = ctypes.string_at(result, -1).decode("utf-8")
result = json.loads(result)
dll.FreeSlice(ss)
print(result)
dll.DestroySdk(new_sdk)
if __name__ == '__main__':
WxWork.sync_msg()
请问下怎么获取媒体文件?
稳定运行半年了,很好用
你好,请问报错段错误,应该怎么办?
解决办法:
对照libwxworkFinanceSdk_c.h中,对于各个函数的声明,通过设置ctypes.func_xxx.restype和ctypes.func_xxx.argtypes指定函数的返回值类型和参数类型。
比如:
libwxworkFinanceSdk_ch.h中GetChatData的声明如下。
int GetChatData(WeWorkFinanceSdk_t* sdk, unsigned long long seq, unsigned int limit, const char *proxy,const char* passwd, int timeout,Slice_t* chatDatas);
那么在python中调用GetChatData,如果不通过ctype规定参数和返回值的类型,就会导致值漂移,出现 段错误。
因此在Python中调用GetChatData要这么写:
原写法:
ret = dll.GetMediaData(new_sdk,indexbuf,sdkfileid.encode(), ”“,”“, 5, media_data)
修正后写法:
dll.GetMediaData.restype = ctypes.c_int
dll.GetMediaData.argtypes = [ctypes.c_void_p, ctypes.c_wchar_p, ctypes.c_char_p, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int, ctypes.c_void_p]
ret = dll.GetMediaData(new_sdk,indexbuf,sdkfileid.encode(), ”“,”“,5, media_data)
每一个函数都需要设置。挺麻烦的。
wxworkFinanceSdk_ch.h中GetChatData的声明:
int GetChatData(WeWorkFinanceSdk_t* sdk, unsigned long long seq, unsigned int limit, const char *proxy,const char* passwd, int timeout,Slice_t* chatDatas);
在Python中调用GetChatData要这么写:
原写法:
d = dll.GetChatData(new_sdk, seq, 1000, ”“, ”“, 5, slice)
修正后写法(要先 import ctypes):
dll.GetChatData.restype = ctypes.c_int
dll.GetChatData.argtypes = [ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_uint, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int, ctypes.c_void_p ]
d = dll.GetChatData(new_sdk, seq, 1000, ”“, ”“, 5, slice)
有go版本吗
求助:有没有遇到服务器ctypes.cdll.LoadLibrary so文件崩溃的?
*** Error in `venv3.6/bin/python': free(): invalid pointer: 0x00007fcdbb73b600 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7fcdd5812bfb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7fcdd5818fc6]
/lib/x86_64-linux-gnu/libc.so.6(+0x7780e)[0x7fcdd581980e]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt6locale5_Impl16_M_install_facetEPKNS_2idEPKNS_5facetE+0x142)[0x7fcdbb3896a2]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt6locale5_ImplC2Em+0x1e3)[0x7fcdbb389b03]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt6locale18_S_initialize_onceEv+0x15)[0x7fcdbb38aa75]
/lib/x86_64-linux-gnu/libpthread.so.0(+0xe759)[0x7fcdd625a759]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt6locale13_S_initializeEv+0x21)[0x7fcdbb38aac1]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt6localeC2Ev+0x13)[0x7fcdbb38ab03]
/utils/libWeWorkFinanceSdk_C.so(_ZNSt8ios_base4InitC1Ev+0xb4)[0x7fcdbb387e54]
/utils/libWeWorkFinanceSdk_C.so(+0x3f6814)[0x7fcdbb37a814]
/utils/libWeWorkFinanceSdk_C.so(+0x45da16)[0x7fcdbb3e1a16]
======= Memory map: ========
55bb6505d000-55bb65303000 r-xp 00000000 fe:01 1057215 /usr/local/bin/python3.6
55bb65502000-55bb65504000 r--p 002a5000 fe:01 1057215 /usr/local/bin/python3.6
55bb65504000-55bb65568000 rw-p 002a7000 fe:01 1057215 /usr/local/bin/python3.6
55bb65568000-55bb65598000 rw-p 00000000 00:00 0
55bb655cf000-55bb65fb1000 rw-p 00000000 00:00 0 [heap]
7fcdb4000000-7fcdb4021000 rw-p 00000000 00:00 0
7fcdb4021000-7fcdb8000000 ---p 00000000 00:00 0