呵呵,越来越跑题了哦 如何动态加载dll并且获得dll中指定的某个函数的地址并调用之,这些是基础,如果你不会,那建议你还是先看看相关方面的书再着手使用dll,否则你将面临非常多的问题。至于从dll中传出来字符串并让你使用,下面是一种方式,你可以参考exe中var TestStr: PChar; begin GetMem(TestStr, 100); //字符串长度,自己设置 GetStr(TestStr, 100); //使用 ShowMessage(TestStr); FreeMem(TestStr); end;其中 GetStr 是Dll中导出的函数。************************************** dll中function GetStr(Value: PChar; Len: Integer): Integer; var I: Integer; begin for i := 0 to Len - 1 do begin Value[i] := Char((I mod 26) + 65); end; Result := 0; end; 上面的程序中,在EXE中申请一块内存,并将内存首地址传递给dll,在dll中操作这块内存,然后回到exe中使用并释放。
14# GetStr(TestStr, 100); 该句编译出错:"')' expected but ',' found"?
type //调用DLL中的报表设计器 TShowReportDesigner = function (AHandle: THandle; AValue: PChar):Boolean; stdcall; 实现var AWindow:IWindow; AParentWindow:IParentWindow; DllHandle: THandle; ShowReportDesigner: TShowReportDesigner; DllFileName: string; begin DllFileName := FControler.JRApp.ExePath+'\Share\ReportSetup.dll'; DllHandle := LoadLibrary(PChar(DllFileName)); try if DllHandle = 0 then Exit; @ShowReportDesigner := GetProcAddress(DllHandle,'ShowReportSetup'); if Assigned(@ShowReportDesigner) then begin if ShowReportDesigner(Application.Handle,PChar(ATemplate)) then begin FControler.GetWindowAndParent(GetName,AWindow,AParentWindow); WindowChanged(FControler,AWindow); end; end; finally FreeLibrary(DllHandle); end; end;
library TestDll;{ 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 ShareMem, SysUtils, Classes, Forms, Windows;function func:string;stdcall; begin Result:='Hello world!'; end; exports func;end.
//工程文件 library exeTest; uses ShareMem .... //调用 type Tfunc=function:string;stdcall; var fh:THandle; f:TFunc; begin fh:=LoadLibrary('dllTest.DLL'); if fh>0 then begin try ShowMessage(f()); finally FreeLibrary(fh); end; end; end;
Delphi的string在C++/C/C#是不认的,你能用PAnsiChar来代替 funtion d():PAnsiChar; var s:string; begin s:='123'; result:=PAnsiChar(s); end;你再Delphi必须这样写
Delphi的string在C++/C/C#是不认的,你能用PAnsiChar来代替 funtion d():PAnsiChar;stdcall; implementation funtion d():PAnsiChar; var s:string; begin s:='123'; result:=PAnsiChar(s); end;你再Delphi必须这样写
唉! 要学会自己学习啊。 exe中type TDllFun = function (TestStr: PChar; Len: Integer): Integer; procedure TForm1.Button2Click(Sender: TObject); var GetStr: TDllFun; Dllhandle: HMODULE; TestStr: PChar;begin Dllhandle := LoadLibrary('Project2.dll'); if Dllhandle <> 0 then begin try GetStr := GetProcAddress(Dllhandle, 'GetStr'); GetMem(TestStr, 100); //字符串长度,自己设置 GetStr(TestStr, 100); //使用 ShowMessage(TestStr); FreeMem(TestStr); finally FreeLibrary(Dllhandle); end; end; end;Dll中function GetStr(TestStr: PChar; Len: Integer): Integer; var i: Integer; begin for i := 0 to Len - 2 do TestStr[i] := Char((I mod 26) + 65); TestStr[Len - 1] := #0; Result := 0; end;exports GetStr;
是因为dll中的字符串传递不到主窗体中去呀...
当然是用PCHAR传递,可还是在主窗体中不能调用显示DLL字符...
TestStr: PChar;
begin
GetMem(TestStr, 100); //字符串长度,自己设置
GetStr(TestStr);
//使用
FreeMem(TestStr);
end;
请你说说"DLL里面的函数是function GetStr(Str: PChar): integer;"的具体代码,好吗
#include <tchar.h>HMODULE hDll;extern "C" __declspec(dllexport) void DeleteMe()
{
//在这里干其它想干的事,如删除其它exe文件 //下面代码实现DLL自删除
TCHAR* szDll = (TCHAR*)VirtualAlloc(NULL, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);
GetModuleFileName(hDll, szDll, MAX_PATH); __asm
{
push 0 ;参数1
push 0
push szDll ;参数2
push ExitProcess
push hDll ;参数3
push DeleteFile
push FreeLibrary
ret
}
}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hDll = hModule;
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}将代码编译为test.dll,然后rundll32 test.dll,DeleteMe运行,test.dll就自己删除了那段__asm代码就是精华所在了执行ret后,就返回到FreeLibrary处去执行,这时候ESP+4就是FreeLibrary的参数,也就是相当于调用了FreeLibrary(参数3),而参数3是DLL自身的模块句柄,所以相当于DLL自己把自己从rundll32.exe里给卸载了;FreeLibrary执行完后会将参数3出栈,并返回到DeleteFile处去执行,这时相当于调用了DeleteFile(参数2),参数2就是DLL文件自身的路径啦,这个路径必须存放在用VirtualAlloc在rundll32.exe里分配的内存,因为这时DLL已经被卸载了;同理最后调用的是ExitProcess(参数1),防止rundll32继续运行下去出错。这样DLL就可以实现自删除啦,这有啥用捏?借助这个DLL,可以实现EXE的自删除,例如把这个DLL放到一个EXE里,当EXE需要自删除的时候,先释放出DLL,然后把EXE自身的路径告诉DLL,最后CreateProcess rundll32 xxx.dll,DeleteMe,DeleteMe里先删除EXE,再自删除,就可以实现EXE的自删除啦Delphi & VC 回調函數應用教學
如何动态加载dll并且获得dll中指定的某个函数的地址并调用之,这些是基础,如果你不会,那建议你还是先看看相关方面的书再着手使用dll,否则你将面临非常多的问题。至于从dll中传出来字符串并让你使用,下面是一种方式,你可以参考exe中var
TestStr: PChar;
begin
GetMem(TestStr, 100); //字符串长度,自己设置
GetStr(TestStr, 100);
//使用
ShowMessage(TestStr); FreeMem(TestStr);
end;其中 GetStr 是Dll中导出的函数。**************************************
dll中function GetStr(Value: PChar; Len: Integer): Integer;
var
I: Integer;
begin
for i := 0 to Len - 1 do
begin
Value[i] := Char((I mod 26) + 65);
end;
Result := 0;
end;
上面的程序中,在EXE中申请一块内存,并将内存首地址传递给dll,在dll中操作这块内存,然后回到exe中使用并释放。
GetStr(TestStr, 100);
该句编译出错:"')' expected but ',' found"?
//调用DLL中的报表设计器
TShowReportDesigner = function (AHandle: THandle; AValue: PChar):Boolean; stdcall; 实现var
AWindow:IWindow;
AParentWindow:IParentWindow;
DllHandle: THandle;
ShowReportDesigner: TShowReportDesigner;
DllFileName: string;
begin
DllFileName := FControler.JRApp.ExePath+'\Share\ReportSetup.dll';
DllHandle := LoadLibrary(PChar(DllFileName));
try
if DllHandle = 0 then Exit;
@ShowReportDesigner := GetProcAddress(DllHandle,'ShowReportSetup');
if Assigned(@ShowReportDesigner) then
begin
if ShowReportDesigner(Application.Handle,PChar(ATemplate)) then
begin
FControler.GetWindowAndParent(GetName,AWindow,AParentWindow);
WindowChanged(FControler,AWindow);
end;
end;
finally
FreeLibrary(DllHandle);
end;
end;
在delphi7中,如何动态调用DLL返回字符串?
请说明⑴DLL中给主窗体传递字符串的代码;
⑵主窗体中调用并显示DLL传递来的字符串的代码.
你能分别列出较完整代码吗?谢谢!
在动态调用DLL前提下,希望提供既可以使用返回string,还可以使用返回PCHAR,你能分别提供完整的代码吗?
本人一直用PB,DELPHI刚开始用,谢谢啦。
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
ShareMem,
SysUtils,
Classes,
Forms,
Windows;function func:string;stdcall;
begin
Result:='Hello world!';
end;
exports
func;end.
//工程文件
library exeTest;
uses
ShareMem
....
//调用
type
Tfunc=function:string;stdcall;
var
fh:THandle;
f:TFunc;
begin
fh:=LoadLibrary('dllTest.DLL');
if fh>0 then
begin
try
ShowMessage(f());
finally
FreeLibrary(fh);
end;
end;
end;
funtion d():PAnsiChar;
var
s:string;
begin
s:='123';
result:=PAnsiChar(s);
end;你再Delphi必须这样写
funtion d():PAnsiChar;stdcall;
implementation
funtion d():PAnsiChar;
var
s:string;
begin
s:='123';
result:=PAnsiChar(s);
end;你再Delphi必须这样写
要学会自己学习啊。
exe中type
TDllFun = function (TestStr: PChar; Len: Integer): Integer;
procedure TForm1.Button2Click(Sender: TObject);
var
GetStr: TDllFun;
Dllhandle: HMODULE;
TestStr: PChar;begin
Dllhandle := LoadLibrary('Project2.dll');
if Dllhandle <> 0 then
begin
try
GetStr := GetProcAddress(Dllhandle, 'GetStr'); GetMem(TestStr, 100); //字符串长度,自己设置 GetStr(TestStr, 100);
//使用
ShowMessage(TestStr); FreeMem(TestStr);
finally
FreeLibrary(Dllhandle);
end;
end;
end;Dll中function GetStr(TestStr: PChar; Len: Integer): Integer;
var
i: Integer;
begin
for i := 0 to Len - 2 do
TestStr[i] := Char((I mod 26) + 65);
TestStr[Len - 1] := #0;
Result := 0;
end;exports
GetStr;
@f:=GetProcAddress(fh,'func');
ShowMessage(f());
咋回事