我需要使用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,我的坏:) :( / p>
再次感谢您的建议,所以这是工作代码:
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.
答案 0 :(得分:6)
如果我是你,我会借此机会将这个函数调用包装在更像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;
备注:强>
external
)而不是显式GetProcAddress
。这大大减少了样板代码的数量。LongBool
。这意味着您的调用代码无需担心错误代码。这使您的调用代码可以更清晰地阅读:
procedure TForm2.Button1Click(Sender: TObject);
var
hasil: string;
begin
hasil := ReadCode(JvFilenameEdit1.Text);
ShowMessage(hasil);
end;
答案 1 :(得分:3)
坚持stdcall;在TDLLFunc声明结束时的指令告诉编译器它正在使用WINAPI调用约定,并且正如Dorin所指出的,如果你使用的是基于unicode的Delphi版本,你可能想要使用PAnsiChar。
答案 2 :(得分:2)
除了另一个答案中提到的stdcall之外,还需要为传递给DLLFunc的pchar指针分配空间。请注意,在C代码中,cResult var定义为char cResult[512];
这意味着调用者为512个字符的char缓冲区保留空间,并将该缓冲区的地址传递给DLL func。
你在Delphi代码中没有做同等的事情。
更改您的Delphi代码,将hasil定义为char数组:
var hasil: array [0..512] of char;
然后将hasil的地址传递给DLLFunc调用:
DLLFunc(PChar(JvFilenameEdit1.Text), @hasil);