python + delphi dll 混合编程
本文为作者原创作品,转载请注明出处。
作者:汉学
原文地址:https://www.cnblogs.com/c2soft/articles/13036777.html
实践中需要在 python 中生成报表,开始尝试使用 PIL 库向空报表图片中插入所需的文字,可是后插入的文字与原有文字不太和谐,后来想到可以使用 delphi 开发 DLL,在DLL中实现报表生成,并由 python 调用 DLL,实践结果如下:
一、用 delphi 开发 DLL
library fr; uses SysUtils, Classes, frxClass, // FastReport 基本类 frxExportImage; // 导出为 jpg 的类 {$R *.res} function ExportJpg(strName: PChar; showSeal: Boolean): Boolean; stdcall; var fr: TfrxReport; feJpg: TfrxJPEGExport; begin fr := TfrxReport.Create(nil); if not fr.LoadFromFile('custom.fr3') then begin fr.Free; Result := False; Exit; end; try //------------- 准备报表内容---------------- // 向报表中插入姓名 TfrxMemoView(fr.FindObject('m_Name')).Text:= strName; TfrxMemoView(fr.FindObject('m_Sex')).Text:= '男'; TfrxMemoView(fr.FindObject('m_Date1')).Text:= FormatDateTime('yyyy 年 m 月 d 日', now()); TfrxPictureView(fr.FindObject('p_seal')).Visible := showSeal; //------------- 报表内容结束---------------- // 下面两行可以显示报表预览窗口,调试用 fr.PrepareReport(); fr.ShowReport(True); // 导出为 JPG 图片 feJpg := TfrxJPEGExport.Create(nil); feJpg.FileName := strName; feJpg.ShowDialog := false; feJpg.SeparateFiles := false; fr.Export(feJpg); Result := True; except fr.Free; feJpg.Free; Result := False; end; end; exports ExportJpg; begin end.
此工程生成 fr.dll 供 python 调用,导出函数 ExportJpg(strName: PChar; showSeal: Boolean),strName 是需要插入报表中的姓名,showSeal指示是否显示公章,生成报表后将自动生成以 strName 为文件名的 JPG 文件。
二、python 调用 DLL 中的函数
# coding: utf-8 from ctypes import * DllObj = WinDLL("fr.dll") if DllObj.ExportJpg("张无忌".encode('gbk'), True): print("OK")
python 代码中参考了《Python 3 ctypes动态链接库DLL字符串只读取第一个字母原因分析》,但是根据文中的方法使用
DllObj.ExportJpg("张无忌".encode('ascii'), True)
向 DLL 传递字符串时发生编码错误,后来改用
DllObj.ExportJpg("张无忌".encode('gbk'), True)
问题得到解决。
三、python 调用 DLL 中的函数并返回字符串
# coding: utf-8 from ctypes import * DllObj = WinDLL("AntiVC.dll") pFile = create_string_buffer(b'edu.cds') libIndex = DllObj.LoadCdsFromFile(pFile) # 返回值的缓冲区,对应于 C 语言中的 char[] pYzm = create_string_buffer(b' ' * 50) pYzmFile = create_string_buffer(b"aaa.jpg") DllObj.GetVcodeFromFile(libIndex, pYzmFile, pYzm) ret=str(pYzm.value, "utf-8") # 去除多余空格 print(ret, len(ret))