我有一个C ++ function
:
long CSP2_API csp2GetPacket(char szData[], long nBcrNr, long nMaxDataSz)
参数是:
szData: buffer where the barcode data is stored in
nBcrNr: the desired barcode’s index (which starts from 0L)
nMaxDataSz: the maximum size of the szData buffer
我处理这个问题的方法是:
type
TBarcode = Array[0..99] of AnsiChar;
function csp2GetPacket(szBarData : TBarCode;
nBarcodeNumber: LongInt;
nMaxLength: LongInt): LongInt cdecl {$IFDEF WIN32}stdcall {$ENDIF}; external 'CSP2.DLL';
并使用...
进行调用procedure TForm1.Button1Click(Sender: TObject);
var
BarCode : TBarcode;
begin
BarCode := #0;
csp2GetPacket(BarCode,0,SizeOf(BarCode));
end;
C ++文档确认它正在使用条形码的标准ASCII
文本。
有没有更好的(更正确的方法)调用C ++ function
?或者这可以接受吗?
答案 0 :(得分:1)
如果您知道条形码数据永远不会超过100个字节,那么您的方法很好,尽管您的函数声明应该更像这样:
type
TBarcode = Array[0..99] of AnsiChar;
function csp2GetPacket(szBarData: TBarCode; nBarcodeNumber: LongInt; nMaxLength: LongInt): LongInt; cdecl; external 'CSP2.DLL';
或者,如果该功能确实在Windows上使用stdcall
而不是cdecl
:
function csp2GetPacket(szBarData: TBarCode; nBarcodeNumber: LongInt; nMaxLength: LongInt): LongInt; stdcall; external 'CSP2.DLL';
无论哪种方式,更正确的函数转换是将szBarData
参数声明为PAnsiChar
而不是:
function csp2GetPacket(szBarData: PAnsiChar; ...) ...
您仍然可以将固定数组变量传递给PAnsiChar
参数。
答案 1 :(得分:0)
此:
long CSP2_API csp2GetPacket(char szData[], long nBcrNr, long nMaxDataSz)
翻译成这样:
function csp2GetPacket(szData: PAnsiChar; nBcrNr, nMaxDataSz: Longint): Longint; <calling-convention>;
您的翻译不正确。在C中,可以将数组降级为指针,但在Delphi中,您实际上会为每个值传递整个数组,因此转换与原始数据不是二进制兼容的。
我假设你有正确的召唤惯例。如果没有,只需删除stdcall
。
我只想使用AnsiString
作为参数,投射到PAnsiChar
,或多或少像:
var
BarCode: AnsiString;
L: Longint;
begin
SetLength(L, 100);
L := csp2GetPacket(PAnsiChar(BarCode), 0, Length(BarCode));
// If csp2GetPacket returns the length, then:
SetLength(BarCode, L);
// Otherwise, this will work too:
BarCode := PAnsiChar(BarCode); // Copies up to and including terminating #0
我不知道缓冲区长度的限制,所以我假设代码长度相同。
我的文章中有关转化主题的更多信息:Pitfalls of converting。