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))

 

posted @ 2020-06-03 12:24  汉学  阅读(673)  评论(0)    收藏  举报