标题: 用Python的ctypes模块调用libeay32.dll中的若干函数 https://scz.617.cn/python/201604271814.txt Python 2.7缺省自带ctypes模块,通过它可以用纯Python代码调用外部动态链接库的 导出函数。如果被调函数的返回值、形参类型涉及结构、指针,使用ctypes并不方便, 此时在Python代码中需要以ctypes要求的格式预定义结构及函数原型。如果被调函数 的返回值类型是int,形参类形是各种整型或"char *",使用ctypes倒是挺方便的, 比如kill()、prctl()之流。 下例就是不方便的那种情形,这段C代码的意图是,已知n/e生成pem文件。 -------------------------------------------------------------------------- RSA *rsa; EVP_PKEY *pkey; rsa = RSA_new(); BN_hex2bn( &rsa->n, "0143" ); BN_hex2bn( &rsa->e, "0B" ); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA( pkey, rsa ); pemfile = fopen( "publickey.pem", "wb" ); PEM_write_PUBKEY( pemfile, pkey ); fclose( pemfile ); RSA_free( rsa ); -------------------------------------------------------------------------- Python的Crypto模块很容易满足原始需求,此处不纠结这个。对于不方便的那种情形, 如果非要试一下ctypes的话,有些汇编级的技巧。 -------------------------------------------------------------------------- #! /usr/bin/env python # -*- coding: cp936 -*- import ctypes so = ctypes.cdll.LoadLibrary( 'libeay32.dll' ) cso = ctypes.cdll.msvcrt so.RSA_new.restype = ctypes.POINTER( ctypes.c_char ) so.EVP_PKEY_assign.argtypes = ( ctypes.c_int, ctypes.c_int, ctypes.POINTER( ctypes.c_char ) ) so.RSA_free.argtypes = [ ctypes.POINTER( ctypes.c_char ) ] rsa = so.RSA_new() n = "0143" so.BN_hex2bn( ctypes.byref( rsa.contents, 16 ), n ) e = "0B" so.BN_hex2bn( ctypes.byref( rsa.contents, 20 ), e ) pkey = so.EVP_PKEY_new() so.EVP_PKEY_assign( pkey, 6, rsa ) pemfile = cso.fopen( "publickey.pem", "wb" ) so.PEM_write_PUBKEY( pemfile, pkey ) cso.fclose( pemfile ) so.RSA_free( rsa ) --------------------------------------------------------------------------