gpt4 book ai didi

delphi - 请帮助如何将C代码转换为Delphi代码(qsBarcode)

转载 作者:行者123 更新时间:2023-12-03 15:41:15 26 4
gpt4 key购买 nike

我需要使用 qsBarcode http://www.qsbarcode.de/en/index.htm 中的 DLL 文件(这里是下载链接http://www.qsbarcode.de/en/download/qsbar39.zip)。该dll会将包含条形码code39的位图图像解码为字符串。

在他们的示例中只有VB和C示例,但我需要在Delphi中使用它。这是 C 中的官方示例代码:

#include <windows.h>
#include <stdio.h>

typedef int (WINAPI * CODE39_PROC)(char *, char *);

int main(int argc, char* argv[])
{
HINSTANCE hinstLib;
CODE39_PROC ProcAdd;
BOOL fFreeResult;

char cFileName[512] = "\0";
char cResult[512] = "\0";
int iReturn = 0;


if(argc < 2) return 0; //no bitmap filename in argv[1]

strcpy(cFileName,argv[1]);

hinstLib = LoadLibrary("qsBar39");
if (hinstLib == NULL) return -1; //can't load lib

ProcAdd = (CODE39_PROC) GetProcAddress(hinstLib, "ReadCode39");
if (NULL == ProcAdd) return -1; //can't access Proc

//dll Proc call
iReturn = (ProcAdd) (cFileName, cResult);
printf("%s", cResult);

fFreeResult = FreeLibrary(hinstLib);

return iReturn;
}

这就是我尝试在 Delphi 中编写的代码

unit uRead;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Mask, JvExMask, JvToolEdit;

type
TDLLFunc = function(namafile: PChar; hasil:PChar):integer;
TForm2 = class(TForm)
JvFilenameEdit1: TJvFilenameEdit;
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const
DLLFunc: TDLLFunc = nil;

var
Form2: TForm2;
DLLHandle: THandle;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
feedback : integer;
hasil:PChar;
begin
DLLHandle := LoadLibrary('qsBar39.dll');
if (DLLHandle < HINSTANCE_ERROR) then
raise Exception.Create('library can not be loaded or not found. ' + SysErrorMessage(GetLastError));

try
{ load an address of required procedure}
@DLLFunc := GetProcAddress(DLLHandle, 'ReadCode39');

{if procedure is found in the dll}
if Assigned(DLLFunc) then
feedback := DLLFunc(PChar(JvFilenameEdit1.Text), PChar(hasil));
showmessage(hasil);
finally
{unload a library}
FreeLibrary(DLLHandle);
end;

end;

end.

当我执行此代码并调试时,hasil 仅包含 #$11'½而它应该返回条形码图像中的一些字符(您可以在 zip 文件中获取文件图像)。请帮助我,谢谢。

<小时/>

最新更新:

@500,谢谢,我已经放了 stdcall

@dthorpe,谢谢,完成

实际上这个建议很好,我的代码应该运行良好,但我错误地把 JvFilenameEdit1.text 而不是 JvFilenameEdit1.FileName,我的错:)

再次感谢您的建议,这是工作代码:

unit uRead;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Mask, JvExMask, JvToolEdit;

type
TDLLFunc = function(namafile: PAnsiChar; hasil:PAnsiChar):integer; stdcall;
TForm2 = class(TForm)
JvFilenameEdit1: TJvFilenameEdit;
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const
DLLFunc: TDLLFunc = nil;

var
Form2: TForm2;
DLLHandle: THandle;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
feedback : integer;
hasil: array [0..512] of char;
begin
DLLHandle := LoadLibrary('qsBar39.dll');
if (DLLHandle < HINSTANCE_ERROR) then
raise Exception.Create('library can not be loaded or not found. ' + SysErrorMessage(GetLastError));

try
{ load an address of required procedure}
@DLLFunc := GetProcAddress(DLLHandle, 'ReadCode39');

{if procedure is found in the dll}
if Assigned(DLLFunc) then
feedback := DLLFunc(PAnsiChar(JvFilenameEdit1.FileName), @hasil);

edit1.Text := StrPas(@hasil);

finally
{unload a library}
FreeLibrary(DLLHandle);
end;

end;

end.

最佳答案

如果我是你,我会利用这个机会将这个函数调用包装在一个更像 Delphi 的包装器中。

function ReadCode39(FileName, Result: PAnsiChar): LongBool; stdcall;
external 'qsBar39';

function ReadCode(const FileName: string): string;
var
cResult: array [0..512-1] of AnsiChar;
begin
if not ReadCode39(PAnsiChar(AnsiString(FileName)), @cResult[0]) then
raise Exception.Create('ReadCode39 failed');
Result := string(cResult);
end;

注释:

  1. 我使用的是隐式 DLL 导入(使用 external),而不是显式 GetProcAddress。这大大减少了样板代码的数量。
  2. 我正在将 C 样式整数代码错误处理转换为 Delphi 异常。根据您的评论,我猜测非零返回值意味着成功。旧版本的 C 没有 bool 类型,使用 0 表示 false,并且每个非零值都计算为 true。将其映射到 Delphi bool 类型的自然方法是使用 LongBool。这意味着您的调用代码不需要担心错误代码。
  3. 所有与空终止字符串之间的转换都在一个例程中处理,您的调用代码也无需关心此类琐事。
  4. 我编写的代码可以在 ANSI 和 Unicode 版本的 Delphi 之间移植。

这可以让你的调用代码读起来更清晰:

procedure TForm2.Button1Click(Sender: TObject);
var
hasil: string;
begin
hasil := ReadCode(JvFilenameEdit1.Text);
ShowMessage(hasil);
end;

关于delphi - 请帮助如何将C代码转换为Delphi代码(qsBarcode),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6066420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com