Entwickler-Ecke

Dateizugriff - externe DLL in eigenes Programm einbinden


speed2k7 - Mo 17.12.07 09:40
Titel: externe DLL in eigenes Programm einbinden
Hi jungs!

Also ich hab da folgendes Problem: Ich arbeite zur zeit an einem IRC-Projekt, wofür ich einen IRC-Bot programmieren möchte. Funktioniert soweit bisher auch alles wie es soll, er kann connecten, auf bestimmte Befehle reagieren etc...

Jetzt möchte ich über diesen Bot allerdings gerne ein anderes Programm steuern, mit der dazugehörigen DLL. Wie kann ich diese DLL jetzt in mein Programm einbinden und die Funktionen der DLL nutzen?

Wäre für jeden Tip dankbar...

Hab grad gesehen dass es auch den Source von der DLL gibt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
library Rushmirc;

{

********************************************************************************
***                                                                            *
***       Example about using invoke function                                  *
***                                                                            *
********************************************************************************

/ftprushinfo {
  %ftpdown = $dll(rushmirc.dll,Invoke,RushApp.TotalDownloadSize)
  %ftpup = $dll(rushmirc.dll,Invoke,RushApp.TotalUploadSize)
  %ftpfxp = $dll(rushmirc.dll,Invoke,RushApp.TotalFXPSize)
  %ftpdownc = $dll(rushmirc.dll,Invoke,RushApp.CurDownloadSize)
  %ftpupc = $dll(rushmirc.dll,Invoke,RushApp.CurUploadSize)
  %ftpfxpc = $dll(rushmirc.dll,Invoke,RushApp.CurFXPSize)
  %ftpstart = $dll(rushmirc.dll,Invoke,RushApp.StartDate)
  %ftpday = $dll(rushmirc.dll,Invoke,RushApp.DayCount)
  %rushver = $dll(rushmirc.dll,Invoke,RushApp.Version)
  %rushpool = $dll(rushmirc.dll,Invoke,RushApp.PoolInfo)
  %rushcontainer = $dll(rushmirc.dll,Invoke,RushApp.Containers.ContainerCount);
  %rushconn = $dll(rushmirc.dll,Invoke,RushApp.Containers.ConnectedSiteCount);
  %rushtran = $dll(rushmirc.dll,Invoke,RushApp.Containers.TransferSiteCount);
  %rushbwu = $dll(rushmirc.dll,Invoke,RushApp.UploadBW);
  %rushbwd = $dll(rushmirc.dll,Invoke,RushApp.DownloadBW);

  echo %rushver
  echo Thread Pool: %rushpool
  echo BandWidth_up: %rushbwu kbps, Bandwidth_dn: %rushbwd kbps
  echo Container: %rushcontainer , Connected: %rushconn , Transfering: %rushtran
  echo from %ftpstart , total %ftpday day. I downloaded %ftpdown MB, uploaded %ftpup MB, FXPed %ftpfxp MB
  echo This Session I downloaded %ftpdownc MB, Uploaded %ftpupc MB, FXPed %ftpfxpc MB

********************************************************************************
***                                                                            *
***       Example about enable callback for return raw result to mIRC          *
***                                                                            *
********************************************************************************

/enablecallback /dll rushmirc.dll EnableCallback

********************************************************************************
***                                                                            *
***       Example about disable callback                                       *
***                                                                            *
********************************************************************************

/disablecallback /dll rushmirc.dll DisableCallback

}


uses
  SysUtils, Messages,  Windows,  Classes,  Forms;

{$R *.RES}
type
  TLoadInfo = packed record
    mVersion: DWORD;
    mHwnd: HWND;
    mKeep: Boolean;
  end;
  PLoadInfo = ^TLoadInfo;

  TCallbackWindow = class
  private
    fWindowHandle: HWnd;
    fIrcHandle: HWnd;

    fhIrcFileMap: THandle;
    fpIrcFileMapData: pchar;
  protected
    procedure WndProc(var Msg: TMessage);
  public
    constructor Create;
    destructor Destroy; override;
  end;

var
  SaveExit                              : Pointer;

  hFileView                             : PChar;
  hFileMap                              : THandle;

  wCallbackWindow                       : TCallbackWindow;

  bEnableCallback                       : boolean;

const
  WM_EXCHANGE                           = WM_USER + 300;

procedure LoadDll(LoadInfo: PLoadInfo); stdcallexport;
begin
  // Tells mIRC to keep our DLL loaded
  LoadInfo.mKeep := TRUE;
  hFileMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 04096'FTPRush');
  hFileView := MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 000);

  wCallbackWindow := TCallbackWindow.Create;

  bEnableCallback := TRUE;
end;

function UnloadDll(mTimeOut: integer): Integer; stdcallexport;
begin
  if mTimeout = 1 then
  begin
    Result := 0;
    exit;
  end;
  UnmapViewOfFile(hFileView);
  CloseHandle(hFileMap);
  FreeAndNil(wCallbackWindow);
  Result := 1;
end;

function Invoke(mWnd: hWnd; aWnd: hWnd; Data: PChar; Parms: PChar;
  Show: Boolean; NoPause: Boolean): Integer; exportstdcall;
var
  TargetWindow                          : THandle;
begin
  TargetWindow := FindWindow('TfmRush'nil);
  if IsWindow(TargetWindow) then
  begin
    StrCopy(hFileview, Data);
    SendMessage(TargetWindow, WM_EXCHANGE, 00);
    StrCopy(Data, hFileView);
    Result := 3;
  end else
    Result := 1;
end;

function RushScript(mWnd: hWnd; aWnd: hWnd; Data: PChar; Parms: PChar;
  Show: Boolean; NoPause: Boolean): Integer; exportstdcall;
var
  CopyDataStruct                        : TCopyDataStruct;
  TargetWindow                          : THandle;
begin
  TargetWindow := FindWindow('TfmRush'nil);
  if IsWindow(TargetWindow) then
  begin
    CopyDataStruct.dwData := 1000;
    CopyDataStruct.cbData := strlen(Data) + 1;
    CopyDataStruct.lpData := Data;
    wCallbackWindow.fIrcHandle := mWnd;
    if bEnableCallback then
      SendMessage(TargetWindow, WM_COPYDATA, wCallbackWindow.fWindowHandle, LParam(@CopyDataStruct))
    else
      SendMessage(TargetWindow, WM_COPYDATA, 0, LParam(@CopyDataStruct));
  end;
  Result := 1;
end;

function EnableCallback(mWnd: hWnd; aWnd: hWnd; Data: PChar; Parms: PChar;
  Show: Boolean; NoPause: Boolean): Integer; exportstdcall;
begin
  bEnableCallback := True;
  Result := 1;
end;

function DisableCallback(mWnd: hWnd; aWnd: hWnd; Data: PChar; Parms: PChar;
  Show: Boolean; NoPause: Boolean): Integer; exportstdcall;
begin
  bEnableCallback := False;
  Result := 1;
end;

function RushCommand(mWnd: hWnd; aWnd: hWnd; Data: PChar; Parms: PChar;
  Show: Boolean; NoPause: Boolean): Integer; exportstdcall;
var
  CopyDataStruct                        : TCopyDataStruct;
  TargetWindow                          : THandle;
begin
  TargetWindow := FindWindow('TfmRush'nil);
  if IsWindow(TargetWindow) then
  begin
    CopyDataStruct.dwData := 1001;
    CopyDataStruct.cbData := strlen(Data) + 1;
    CopyDataStruct.lpData := Data;
    SendMessage(TargetWindow, WM_COPYDATA, 0, LParam(@CopyDataStruct));
  end;
  Result := 1;
end;

procedure LibExit;
begin
  ExitProc := SaveExit; // restore exit procedure chain
end;

exports
  LoadDll,
  UnloadDll,
  RushScript,
  RushCommand,
  EnableCallback,
  DisableCallback,
  Invoke;
{ TCallbackWindow }

constructor TCallbackWindow.Create;
begin
  fWindowHandle := AllocateHWnd(WndProc);

  FhIrcFileMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 04096'mIRC');
  FpIrcFileMapData := MapViewOfFile(FhIrcFileMap, FILE_MAP_ALL_ACCESS, 000);
end;

destructor TCallbackWindow.Destroy;
begin
  DeallocateHWnd(fWindowHandle);
  UnmapViewOfFile(FpIrcFileMapData);
  CloseHandle(FhIrcFileMap);
  inherited;
end;

const {Store at WM_COPYDATA Message: wParam}
  FTPRUSH_CALLBACK_RAWCOMMAND           = 888//THIS IS FROM http://FTP.RAW

const {Store at WM_COPYDATA Struct : dwData}
  CALLBACK_SUCCESS                      = 1;
  CALLBACK_FAILED                       = 0;

const
  ctrlLink                              = #10// link
  ctrlb                                 = #2// bold
  ctrlc                                 = #3// color
  ctrld                                 = #4// bersirc (RGB) color
  ctrlo                                 = #15// normal
  ctrlq                                 = #17// fixed width font
  ctrlr                                 = #18// switch fg/bg
  ctrlv                                 = #22// italics
  ctrl_                                 = #31// underline

procedure TCallbackWindow.WndProc(var Msg: TMessage);
var
  pCopyDataStruct                       : ^CopyDataStruct;
  LLines                                : TStringList;
  LSiteName                             : string;
  LRawCommand                           : string;
  I                                     : Integer;

  procedure SendMessageTomIRC(const AMessageLine: string);
  begin
    StrPCopy(FpIrcFileMapData, AMessageLine);
    SendMessage(fIrcHandle, WM_USER + 20010);
  end;
begin
  case Msg.Msg of //
    WM_COPYDATA:
      begin
        LLines := TStringList.Create;
        try

          case Msg.WParam of //
            FTPRUSH_CALLBACK_RAWCOMMAND:
              begin
                pCopyDataStruct := pointer(Msg.LParam);
                LLines.Text := PChar(pCopyDataStruct^.lpData);

                if pCopyDataStruct^.dwData = CALLBACK_SUCCESS then
                begin
                  { When Success,
                    first line is sitename,
                    second line is the raw command,
                    other lines are FTP raw command result
                  }

                  if LLines.Count > 0 then
                  begin
                    LSiteName := LLines.Strings[0];
                    if LLines.Count > 1 then
                      LRawCommand := LLines.Strings[1];

                    //Send Command to mirc
                    SendMessageTomIRC('/echo -a ' + Format('(%s) '#2'%s', [LSiteName, LRawCommand]));

                    for I := 2 to LLines.Count - 1 do
                      SendMessageTomIRC('/echo -a ' + Format('(%s) %s', [LSiteName, LLines.Strings[I]]));
                  end;

                end;
              end;
          end// case

        finally
          LLines.Free;
        end;
      end;
  end// case
  Msg.Result := 1;
end;

begin
  SaveExit := ExitProc; // save exit procedure chain
  ExitProc := @LibExit; // install LibExit exit procedure
end.


kann ich diese library genauso wie eine Unit in mein Programm einbinden?

mfg sPeeD2k7

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt


Delete - Mo 17.12.07 12:57

Das ist eine Plugin-DLL. Die musst du dynamisch mit LoadLibrary laden und dann die Funktionen ebenbso mit GetProcAddress. Wad du d agneau wie laden musst, sollte in der Dokumentation stehen.


speed2k7 - Mo 17.12.07 15:19

und woran sehe ich, dass man die DLL dynamisch einbinden muss?


Delete - Mi 19.12.07 18:29

Dynamisch muss natürlich nicht unbedingt sein, aber auf alle Fälle müssen die Funktionen LoadDLL und UnLoaDdll aufgerufen werden.