Delphi 有人能帮我解决这个错误吗?我在尝试用dll打开端口时遇到了这个错误
有人能帮我解决这个错误吗?我在尝试用dll打开端口时遇到了这个错误。当我呼叫SAAT_Open(myCharPtrOpen)时,我收到一个错误:“地址0003D078处的访问冲突”。不确定我是否在单元API上正确定义了句柄。变量幻影定义正确吗? 这是我的密码:Delphi 有人能帮我解决这个错误吗?我在尝试用dll打开端口时遇到了这个错误,delphi,dll,tcp,Delphi,Dll,Tcp,有人能帮我解决这个错误吗?我在尝试用dll打开端口时遇到了这个错误。当我呼叫SAAT_Open(myCharPtrOpen)时,我收到一个错误:“地址0003D078处的访问冲突”。不确定我是否在单元API上正确定义了句柄。变量幻影定义正确吗? 这是我的密码: procedure TForm5.Button1Click(Sender: TObject); var myString, myString2 : string; myCharPtrInit: PChar; myCh
procedure TForm5.Button1Click(Sender: TObject);
var
myString, myString2 : string;
myCharPtrInit: PChar;
myCharPtrOpen: PChar;
i : Integer;
Open, Init: Boolean;
begin
// Create a string of Char's
myString := '&hp';
// Point to the first character in the string
i := 1;
myCharPtrInit := Addr(myString[i]);
if SAAT_TCPInit(myCharPtrInit,'192.168.3.238',7086) = True then
begin
StatusBar1.Panels[0].Text := 'Initiated'; //ShowMessage('Initiated');
myString2 := 'hp';
myCharPtrOpen := Addr(myString2[i]);
if SAAT_Open(myCharPtrOpen) = True then StatusBar1.Panels[1].Text := 'Opened';
end;
end;
unit UntRFIDAPI;
INTERFACE
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls, Dialogs,
StdCtrls, Forms, DBCtrls, DB, Grids, DBGrids,Mask, ExtCtrls,
Buttons, WinTypes;
var
A: String;
function SAAT_TCPInit(pHandle: Pointer; pHostName: String; nsocketPort: Integer):Boolean; stdcall;
function SAAT_Open(pHandle: Pointer):Boolean; stdcall;
function SAAT_Close(pHandle: Pointer):Boolean; stdcall;
implementation
function SAAT_TCPInit; external 'RFIDAPI.dll';
function SAAT_Open; external 'RFIDAPI.dll';
function SAAT_Close; external 'RFIDAPI.dll';
end.
以下是API调用:
1.1初始化以太网端口(TCP)连接
//TCP parameters initialization
//Functionality:import by parameter, initialize TCP to prepare for opening connection
//Parameters:
// pHandle for preserving the opening ports handl
// pHostName reader IP address, only effective under the ethernet communication
// nsocketPort network SOCKET port
//Returned value:true: Operation Succeeded, false Operation Failed
bool SAAT_TCPInit (void** pHandle,char *pHostName,int nsocketPort)
如果连接到读卡器的IP为192.168.0.238,端口为7086,则按如下方式调用:
HANDLE hp;
if (!SAAT_TCPInit(&hp, ”192.168.0.238”, 7086))
{
printf("reader initialization failed!\n");
return false;
}
此函数生成类型为void*
的新句柄。在映射到指针的Delphi中,一种非类型指针。因为C只支持按值传递,为了让函数将值传递给调用者,参数被声明为指向void*
,即void**
char*
是一个输入参数,指向以null结尾的8位字符数组的指针。映射到PAnsiChar
。绝对不能使用字符串
进行互操作。它是一个私有的Delphi类型,对于互操作来说根本无效
由于没有指定调用约定,我们假设它是cdecl
因此,正确的翻译是:
function SAAT_TCPInit(out Handle: Pointer; HostName: PAnsiChar;
SocketPort: Integer): Boolean; cdecl; external 'RFIDAPI.dll';
我们已经将句柄类型,void*
映射到指针
。而out
的使用引入了所需的额外间接级别
可以这样称呼:
var
Handle: Pointer;
....
if SAAT_TCPInit(Handle, '192.168.3.238', 7086) then
....
function SAAT_Open(Handle: Pointer): Boolean; cdecl; external 'RFIDAPI.dll';
DLL中的函数实际上是stdcall
,这似乎是合理的,即使您提供的C原型没有指定这一点。如果是这样的话,并且只有您能够解决这个问题,那么您可以相应地更改调用约定。事实上,Remy已经找到了头文件,并显示了函数是stdcall
我们看不到另一个函数的C声明,但它们看起来非常简单。它们似乎都接受调用SAAT\u TCPInit
返回的句柄。因此,它们应该接受一个类型为指针
、由值传递的参数。大概是这样的:
var
Handle: Pointer;
....
if SAAT_TCPInit(Handle, '192.168.3.238', 7086) then
....
function SAAT_Open(Handle: Pointer): Boolean; cdecl; external 'RFIDAPI.dll';
同样,对于SAAT_Close
为了清晰起见,为这个句柄定义一种新类型可能会更好。像这样:
type
TSAATHandle = type Pointer;
或者如果您愿意:
type
TSAATHandle = type NativeUInt;
很明显,您会使用这种类型,而不是指针
此函数生成类型为void*
的新句柄。在映射到指针的Delphi中,一种非类型指针。因为C只支持按值传递,为了让函数将值传递给调用者,参数被声明为指向void*
,即void**
char*
是一个输入参数,指向以null结尾的8位字符数组的指针。映射到PAnsiChar
。绝对不能使用字符串
进行互操作。它是一个私有的Delphi类型,对于互操作来说根本无效
由于没有指定调用约定,我们假设它是cdecl
因此,正确的翻译是:
function SAAT_TCPInit(out Handle: Pointer; HostName: PAnsiChar;
SocketPort: Integer): Boolean; cdecl; external 'RFIDAPI.dll';
我们已经将句柄类型,void*
映射到指针
。而out
的使用引入了所需的额外间接级别
可以这样称呼:
var
Handle: Pointer;
....
if SAAT_TCPInit(Handle, '192.168.3.238', 7086) then
....
function SAAT_Open(Handle: Pointer): Boolean; cdecl; external 'RFIDAPI.dll';
DLL中的函数实际上是stdcall
,这似乎是合理的,即使您提供的C原型没有指定这一点。如果是这样的话,并且只有您能够解决这个问题,那么您可以相应地更改调用约定。事实上,Remy已经找到了头文件,并显示了函数是stdcall
我们看不到另一个函数的C声明,但它们看起来非常简单。他们都似乎都接受调用SAAT\u TCPInit
返回的句柄。因此,它们应该接受一个类型为指针
、由值传递的参数。大概是这样的:
var
Handle: Pointer;
....
if SAAT_TCPInit(Handle, '192.168.3.238', 7086) then
....
function SAAT_Open(Handle: Pointer): Boolean; cdecl; external 'RFIDAPI.dll';
对于SAAT_Close
,情况也类似
为了清晰起见,最好为该手柄定义一种新类型。像这样:
type
TSAATHandle = type Pointer;
或者如果您愿意:
type
TSAATHandle = type NativeUInt;
很明显,您会使用这种类型,而不是指针 您对C标题的翻译非常糟糕。我没有其他函数的原型,但是SAAT\u TCPInit
应该声明为:
function SAAT_TCPInit(var pHandle: THandle; pHostName: PAnsiChar; nSocketPort: Integer): ByteBool;
cdecl;
C对Delphi字符串一无所知,所以不要将C字符串翻译为Delphi的类型string
,因为它与二进制文件不兼容char*
应翻译为PAnsiChar
void**pHandle
应翻译为var pHandle:THandle
。调用约定可能是cdecl
这假定使用正常校准约定。如果将其设置为生成stdcall
,则必须声明它,而不是cdecl
我想这是你的主要问题。请更正翻译,然后重试
有关翻译C标题的更多信息,请参阅我的文章(立即获取,因为网站可能会离线一段时间,我将切换提供商)。您的C标题翻译几乎处于关闭状态。我没有其他函数的原型,但是SAAT\u TCPInit
应该声明为:
function SAAT_TCPInit(var pHandle: THandle; pHostName: PAnsiChar; nSocketPort: Integer): ByteBool;
cdecl;
C对Delphi字符串一无所知,所以不要将C字符串翻译为Delphi的类型string
,因为它与二进制文件不兼容char*
应翻译为PAnsiChar
void**pHandle
应翻译为var pHandle:THandle
。调用约定可能是cdecl
这假定使用正常校准约定。如果设置为生成stdcall
,则您必须声明它,而不是cd