用Indy 控件写一个Telnet的dll 出现的问题?急急 !!!

PowerSoft-001 2003-12-19 03:48:48
小弟由于要通过Windows客户端发批命令去一台Linux主机上执行相关命令,因此想用Indy控件写一个通过telnet方式去执行命令的dll来供其他开发工具调用。
由于我第一次写DLL,出现问题很大。
调用出现主要错误提示如下:
---------------------------
Debugger Exception Notification
---------------------------
Project Project2.exe raised exception class EAccessViolation with message 'Access violation at address 00245DD9 in module 'Project1.dll'. Read of address 00000000'. Process stopped. Use Step or Run to continue.

现把源代码发布如下:(敬请高手指正)

DLL部分:
library project1;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes,
IdTCPConnection, IdTCPClient, IdTelnet;

//{$R *.res}

Function Telnet(host,user,pwd,command:pchar;handle:Thandle) :integer;stdcall;
var
i : integer;
lhost,luser,lpwd,lcommand:string;
IdTelnetDemo: TIdTelnet;
begin

lhost:=string(host);
luser:=string(user) ;
lpwd:=string(pwd);
lcommand:=string(command) ;
try
//CoInitialize(nil);
IDTelnetDemo.Create(nil);
IDTelnetDemo.Host :=lhost;
IDTelnetDemo.port :=23;
IdTelnetDemo.Connect;
if IdTelnetDemo.Connected then
begin
for i := 1 to length(luser) do
begin
IdTelnetDemo.SendCh(luser[i]);
IdTelnetDemo.SendCh(#13);
end;
for i:= 1 to length(lpwd) do
begin
IdTelnetDemo.SendCh(lpwd[i]);
IdTelnetDemo.SendCh(#13);
end;
for i:= 1 to length(lcommand) do
begin
IdTelnetDemo.SendCh(lcommand[i]);
IdTelnetDemo.SendCh(#13);
end;

result:=1;
IdTelnetDemo.Disconnect;
end
else
result:=2;
//except
//result:=3;
finally
begin
IdTelnetDemo.Destroy;
end;
end;



end;

exports
Telnet;
end.


Delphi调用程序部分:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons;

type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
edtID: TEdit;
edtUser: TEdit;
edtHost: TEdit;
GroupBox2: TGroupBox;
Memo1: TMemo;
BitBtnOK: TBitBtn;
BitBtnCancel: TBitBtn;
procedure BitBtnCancelClick(Sender: TObject);
procedure BitBtnOKClick(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;
Function Telnet(host:string;user:string;id:string;command:string) :integer;stdcall;
var
Form1: TForm1;

implementation
{$R *.dfm}
Function Telnet;external 'Project1.dll' name 'Telnet';

procedure TForm1.BitBtnCancelClick(Sender: TObject);
begin
close;
end;

procedure TForm1.BitBtnOKClick(Sender: TObject);
var
host,user,id,command :string;
i:integer;
begin
host:='192.168.5.2';
user:='bonny';
id:='happysky';
command:='mkdir telnet';
i:=Telnet(pchar('192.168.5.2'),pchar('bonny'),pchar('happysky'),pchar('mkdir telnet'));
edtuser.text:=inttostr(i);
end;

end.

这个调用程序是一个Demo,最终结果是想传一个批处理命令给Linux主机去执行。用户只要在客户机上点击一下相关选项就行了。
现在问题只是在传递参数过程中出现问题,不知这种方式的可执行程度如何,且程序当中还有未知的问题敬请高手指教。

谢谢!!!
...全文
98 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
PowerSoft-001 2003-12-30
  • 打赏
  • 举报
回复
To halfdream:

我把它改放在一个数据模块(TDataModule)里了,不用form了,在dll入口函数处创建了这个TIdTelnet实例。
但发现又一问题:

在调用connect方法后,IdTelnetDemoDataAvailable事件没有响应。但是如果不用dll,在普通delphi里调用indy控件的telnet控件事,一样情况下IdTelnetDemoDataAvailable事件是有响应的。

敬请指教!!

PowerSoft-001 2003-12-22
  • 打赏
  • 举报
回复
你好,halfdream!传参数的问题我已经解决了。也就是上面的故障已经解决了!
现在又出现一个新问题。也可能是我的实现方法上有错误。
在这里再重新讲述一下我要解决的问题:
用delphi写一个Dll,这个dll主要实现通过telnet协议与unix主机通信。然后供其他应用程序调用。(主要用处是通过它发命令给unix主机去执行)。我想,这大概就是WinSocket编程范围了。我看到delphi提供了indy控件,所以我想通过indy控件集合中telnet控件来实现它。但是现在好像用普通dll方式不行,大概必须要用Activex方式包装才行。应为indy控件的Create(AOwner: TComponent)方法中的参数AOwner必须是一个容器控件。

我现在思想比较混乱,敬请高手指教!!
halfdream 2003-12-22
  • 打赏
  • 举报
回复
普通DLL不行?怎么会呢?

它需要注意的一个处理地方是.TELNET是长连接的,你要让idTcpclient对象保持在内存中.

另外,普通DLL同COM的DLL都是动态库,装入内存这方面是一样的.

indy控件它创建需要OWNER,那你就把它扔在一个数据模块吧,
在DLL里面动态创建这个数据模块还可靠些.
halfdream 2003-12-21
  • 打赏
  • 举报
回复
这样实现是可行的,你跟踪执行一下这个DLL先自己找找出错的地方.
PowerSoft-001 2003-12-21
  • 打赏
  • 举报
回复
为何每人回答呀?
PowerSoft-001 2003-12-20
  • 打赏
  • 举报
回复
up
PowerSoft-001 2003-12-19
  • 打赏
  • 举报
回复
刚才Delphi调用程序部分那个函数Telnet声明部分贴错了,应该如下:

Function Telnet(host,user,id,command:pchar) :integer;stdcall;

但是错误还是如上所示。敬请指教!!

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧