TC官方合作论坛

 找回密码
 立即注册
查看: 4662|回复: 6

[讨论] dllcall 用法例子之下载者

[复制链接]
发表于 2014-3-1 16:25:50 | 显示全部楼层 |阅读模式

马上加入TC

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
  1. 空间 dllcalltest
  2. //默认空间
  3. 变量 线程句柄=0

  4. //dllcall参数说明
  5. //函数原型:dllcall(filepath,type,functionName,...)

  6. //filepath:api所在的一个dll的地址

  7. //type:api返回值的类型

  8. //functionName:api的名字,某些字符串相关的API在名字需要多加字母A或者W

  9. //...:表示参数是动态的,后面的实际参数是根据API的具体参数来写的



  10. //dllcall使用规则:
  11. //1、调用系统API只需要写API所在的dll就可以了,可以不写绝对路径,自己编写的API必须使用绝对路径

  12. //2、 dllcall的参数在TC里面的定义:

  13. //TC代码中的参数
  14. //MSDN中的参数

  15. //wchar *
  16. //LPCWSTR

  17. //char *

  18. //LPTSTR LPCTSTR

  19. //double
  20. //DOUBLE FLOAT

  21. //int
  22. //INT LONG

  23. //bool
  24. //BOOL


  25. //3、参数的个数以及类型必要与MSDN上相对应

  26. //4、dllcall暂时还不支持参数传址与结构体


  27. 功能 下载文件(pCaller,szURL,szFileName,dwReserved,lpfnCB)
  28.     //VB
  29.     //Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA"
  30.     //(ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String,ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
  31.    
  32.     //Return Value
  33.     //Returns one of the following values.
  34.    
  35.     //S_OK : The download started successfully.
  36.    
  37.     //E_OUTOFMEMORY: The buffer length is invalid, or there is insufficient memory to complete the operation.
  38.    
  39.     //INET_E_DOWNLOAD_FAILURE:The specified resource or callback interface was invalid.
  40.    
  41.     返回值=dllcall("urlmon.dll","int","URLDownloadToFileA","int",pCaller,"char *",szURL,"char *",szFileName,"int",dwReserved,"int",lpfnCB)
  42.     如果(返回值==0)
  43.         返回 真
  44.     否则
  45.         返回 假
  46.     如果结束
  47. 功能结束

  48. 功能 打开文件(lpCmdLine,nCmdShow)
  49.     //VB
  50.     //Declare Function WinExec Lib "kernel32" Alias "WinExec" (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As Long
  51.     //返回值
  52.     //Long,大于31表示成功,请参考FindExecutable函数
  53.     返回值=dllcall("kernel32.dll","int","WinExec","char *",lpCmdLine,"int",nCmdShow)
  54.     调试输出("打开文件返回值数值:"&返回值)
  55.     如果(返回值>31)
  56.         返回 真
  57.     否则
  58.         返回 假
  59.     如果结束
  60. 功能结束

  61. 功能 主功能()
  62.     Url="http://www.52kanpai.com/test.exe"
  63.     UrlToFlie="c:\\test.exe"
  64.     是否下载成功=dllcalltest.下载文件(0,Url,UrlToFlie,0,0)
  65.     如果(是否下载成功)
  66.         调试输出("下载成功,返回值:"&是否下载成功)
  67.         是否打开成功=dllcalltest.打开文件(UrlToFlie,1)
  68.         如果(是否打开成功)
  69.             调试输出("成功打开文件")
  70.         否则
  71.             调试输出("打开文件失败")
  72.         如果结束
  73.     否则
  74.         调试输出("下载失败,返回值:"&是否下载成功)
  75.     如果结束
  76. 功能结束


  77. 功能 开启下载线程_点击()
  78.     //这里添加你要执行的代码
  79.     如果(线程句柄==0)
  80.         线程句柄=线程.开启("dllcalltest.主功能","")
  81.     如果结束
  82. 功能结束

  83. //空间结束语句
  84. 功能 结束下载线程_点击()
  85.     //这里添加你要执行的代码
  86.     线程.关闭(线程句柄)
  87.     线程句柄=0
  88. 功能结束
  89. 空间结束

复制代码

回复

使用道具 举报

 楼主| 发表于 2014-3-1 16:31:56 | 显示全部楼层
我的理解是,编程就是调用系统提供的API接口做一些我们想做的事情。。。。
TC的DLLCALL 功能对于功能的扩展有很大的帮助啦,方便直接用TC扩展程序功能。。。
但是,为什么TC只能编写EXE形态的程序呢? 例如DLL就不支持。。
很多情况下需要用DLL的,例如DLL劫持。。。小伙伴们都懂的。。

而像易语言就可以写DLL。。

不知道TC啥时候加上呢?
回复 支持 反对

使用道具 举报

发表于 2014-3-1 16:37:42 | 显示全部楼层
这不一样tc只是为了脚本开发,是一门脚本语言
而易语言是为了开发一门中文编程语言而开发的,类似vb的中文版,但是有自个的编译器,不是解释型语言
回复 支持 反对

使用道具 举报

发表于 2014-3-1 16:37:44 | 显示全部楼层
本帖最后由 jimye0526 于 2014-3-1 16:39 编辑

_____
回复

使用道具 举报

 楼主| 发表于 2014-3-1 16:41:50 | 显示全部楼层
但是,有时候注入后才方便,注入又是DLL才方便。 那TC不能玩DLL啊。。
回复 支持 反对

使用道具 举报

发表于 2014-3-1 21:05:20 | 显示全部楼层
你可以用E写DLL 然后TC调用
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-2 07:56:14 | 显示全部楼层
1. 静态调用方式

示例程序创建了一个DLL,其中仅包含一个求两个整数的和的函数,在主程序中输入两个整数,通过调用该DLL,即可求出两个整数的和
  1. library AddNum;
  2. uses
  3. SysUtils,
  4. Classes;

  5. {$R *.res}

  6. function AddNumber(Num1,Num2:integer):integer;stdcall; //定义求和函数
  7.  begin
  8.   result:=Num1+Num2;
  9.  end;
  10.   exports
  11.   AddNumber; //引出求和函数
  12.  begin
  13. end.
复制代码

主程序在调用该DLL时,首先在interface部分声明要调用的函数:
  1. function AddNum(Num1,Num2:integer):integer;stdcall;external 'AddNum.dll'
  2. name 'AddNumber';
复制代码

然后在按钮控件的事件中写入如下代码:
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.  Number1,Number2:integer;
  4.  Sum:integer;
  5. begin
  6.  Number1:=strtoint(Edit1.Text);
  7.  Number2:=strtoint(Edit2.Text);
  8.  Sum:=AddNum(Number1,Number2); //调用求和函数计算结果
  9.  Edit3.Text:=inttostr(Sum);
  10. end;
复制代码

2.动态调用方式

这个示例程序创建了一个显示日期的DLL,其中包含一个窗体。

程序中定义了一个ShowCalendar函数,返回在这个窗体中设定的日期。函数定义如下
  1. function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;
  2. var
  3.  DLLForm: TDLLForm;
  4. begin
  5.  Application.Handle := AHandle;
  6.  DLLForm := TDLLForm.Create(Application); //创建并显示窗体
  7.  try
  8.   DLLForm.Caption := ACaption;
  9.   DLLForm.ShowModal; //显示方式为模式化
  10.   Result := DLLForm.calDLLCalendar.CalendarDate; //返回设定日期
  11.  finally
  12.   DLLForm.Free; //用完后卸载该窗体
  13.  end;
  14. end;
复制代码

在DLL的工程文件中用exports ShowCalendar; 语句引出该函数。下面通过一个简单的应用程序测试一下该DLL文件。新建一个工程文件,在窗体中放置一个Label控件和一个按钮控件,在按钮控件的OnClick事件中编写如下代码:
  1. procedure TMainForm.Button1Click(Sender: TObject);
  2. var
  3.  OneHandle : THandle; //定义一个句柄变量
  4. begin
  5.  OneHandle := LoadLibrary('Clendar.dll'); //动态载入DLL,并返回其句柄
  6.  try
  7.   if OneHandle <> 0 then //如果载入成功则获取ShowCalendar函数的地址
  8.    @ShowCalendar := GetProcAddress(OneHandle, 'ShowCalendar');
  9.    if not (@ShowCalendar = nil) then
  10.     //如果找到该函数则在主窗体的Label1中显示DLL窗体中设定的日期
  11.     Label1.Caption := DateToStr(ShowCalendar(Application.Handle, Caption))
  12.    else
  13.     RaiseLastWin32Error;
  14.  finally
  15.   FreeLibrary(OneHandle); //调用完毕收回DLL占用的资源
  16.  end;
  17. end;
复制代码


以上为DELPHI中调用DLL的两种方法,DLLCALL方法对比后发现等同于静态调用。TC貌似不可以动态调用。。

没有 LoadlibraryA. GetProcAddress
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18045623号)

GMT+8, 2024-9-24 11:49 , Processed in 0.035123 second(s), 22 queries .

Powered by 海安简单软件服务部

© 2008-2019 版权所有 保留所有权利

快速回复 返回顶部 返回列表