如何使DLL能获得自身绝对路径,并交付使用? ( 积分: 100 )

  • 主题发起人 主题发起人 穿红衣服的小黄
  • 开始时间 开始时间
穿

穿红衣服的小黄

Unregistered / Unconfirmed
GUEST, unregistred user!
首先,我想实现的目标是 建一个能返回自身绝对路径的dll文件,供别人调用,获得dll自身的绝对路径(不是通过别过告诉它).
以下是我自己试着弄的 dll 编译环境 WINXP SP2 + DELPHI7.0
library getpath;
uses
SysUtils,windows,
Classes;

{$R *.res}

function GETDPATH : string ; stdcall
var
path:STRING;
module:hmodule;
buf:array[0..255] of char;
n:integer;

begin
//path:=nil;
module := GetModuleHandle('getpath.dll');
GetModuleFileName(module, buf, sizeof(buf));
for n:=0 to 255 do
begin
path:=path+buf[n];
end;
result:=path;

end;
exports
GETDPATH;
begin
end.

然后又弄了个 exe 去试着调用看结果 (一个edit 一个 button) 如下
function GETDPATH():string;stdcall
external 'getpath'

procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text:= getdpath;
end;

end.
但是点击按钮后,老是报错 ,错误内容 "invalid pointer operation"
edit 里又能得到正确的路径.

这个dll 是想供一个 BI工具去调用
该BI工具 有一个dll 函数可以加载外部dll文件
DLL(P1;P2;P3) P1为dll文件名 p2 为dll中需调用的函数名 P3为 返回值和输入值类型
如 dll("getpath";"getdpath";"BD") = 参数类型 D 返回值类型 B P3的内容如下
Code Description Input via C-Declaration
-----------------------------------------------------------------------------
A Boolean value (0=False, 1=True) Value short int
B 8-Byte floating point number Value (Windows) double
C String with 0 as delimiter Reference char
(max. length = 255 characters)
D String with a byte counter Reference unsigned char
(the first byte indicates the length;
max. length = 255 characters)
E 8-Byte floating point number Reference double
H Two byte unsigned integer Value unsigned short int
I Two byte signed integer Value short int
J Four byte signed integer Value long int
M Two byte signed integer Reference short int
N Four byte signed integer Reference long int
------------------------------------------------------------------------------
在dll被 测试EXE调用 报错后,找不到解决的办法,然后在对应的 A-N代码中有找不到合适
的返回值类型,几个都试过了(如 dll("getpath";"GETDPATH";"D") ) ,都报内部错误,
想请各位能给整理下我的 dll文件代码 和 调用EXE 看是什么原因报错
然后找找 在 BI 里调用 该用什么返回值类型好,并相应的改改 DLL 代码

谢谢各位了!!!
谢谢!!
 
是否应去掉stdcall
我编的dll可以使用。
 
<转自>http://freecoder.blogcn.com/diary,104557726.shtml
关于如何在DLL中获取自身路径和句柄

这个问题研究了比较久,一直没找到很好的解决方法。
后来某一天,居然在睡觉的时候迷迷糊糊的胡思乱想想出来了(汗死。。。)。。。
想通以后其实挺简单的。

首先获取自己的DLL句柄。
技巧就在这里了。
DLL的句柄其实就是DLL加载在内存中的基地址。先讲一下如何获取句柄吧,这里拿Delphi来说吧~原理都差不多的。
首先用:
Function GetEIP : Dword; //获取EIP
asm
Call @Back
@Back: pop eax
end;
呵呵,都看的懂吧,这个函数的功能就是获取EIP寄存器的经典方法。也许有人问,获取EIP又怎样呢?
其实,可以保证的是EIP的数据所指向的地址绝对是在我们的DLL的代码段中。那么,我们只要遍历自身进程中的所有模块,然后选一个句柄在EIP的前面,但是又最接近EIP的句柄就是我们想要的句柄了。即,在保证<EIP的前提下使得EIP-Handle最小,此时的Handle为所求。关于遍历模块列表,可以使用PSAPI函数,也可以使用Tlhelp32的函数。个人比较喜欢PSAPI。下面给出获取自身句柄的函数,注意需要先uses PSAPI;

Function GetMyHandle : DWord;
Function GetEIP : Dword; //获取EIP
asm
Call @Back
@Back: pop eax
end;

var
Modules : Array [1..MAX_PATH] of DWord;
Needed : DWord;
Count : integer;
Nearest : DWord;
MyEIP : DWord;
i : integer;
begin
MyEIP:=GetEIP;
EnumProcessModules(GetCurrentProcess, @Modules, sizeof(Modules), needed);
Count:=Needed div 4;
Nearest:=0;
for i:=1 to Count do
if (Modules<MyEIP) and (Modules>Nearest) then Nearest:=Modules;
Result:=Nearest; //最近的句柄为所求。
end;

获取句柄后再获取路径就很简单了,直接用GetModuleFileName函数就OK了~~~

不知道对你有没有帮助
 
Function GetCurrentModuleName: PChar; Stdcall;
Begin
Result := PCHar(GetModuleName(HInstance));
End;



function GetCurrentModuleName():PChar;stdcall;external 'dll文件名'
这么麻烦,这样就行啦
 
来自:Jams, 时间:2007-6-22 23:52:05, ID:3802103
是否应去掉stdcall
我编的dll可以使用。

去掉stdcall 好像不能调用了啊 兄弟,至少我这里是的
 
来自:风铃夜思雨, 时间:2007-6-23 8:39:08, ID:3802139
Function GetCurrentModuleName: PChar; Stdcall;
Begin
Result := PCHar(GetModuleName(HInstance));
End;

function GetCurrentModuleName():PChar;stdcall;external 'dll文件名'

风铃夜思雨 的方法可行, 在BI工具里能获取绝对路径,
delphi 里 edit1.Text:= strpas(GetCurrentModuleName) 为什么得到的是 ……dll.dX 这样的呢?
有什么方法能去掉dllname.dll吗
不需要文件名的. 有比自己判断最后一个'/'字符再截取更方便的办法吗?
好像没有 getmodula 的 path一类的函数吧
 
哥们儿,Delphi开发DLL的一大禁忌就是不能在输出函数中使用string类型,不管是参
数还是返回值。可以用PChar来代替,难道你不知道吗?如果非要用,那么必须包括单元
ShareMem。
 
谢谢各位,目前来说,要实现的功能出来了. 具体怎么优化怎么简单,有空再去弄了

谢谢各位. 散分!
 
后退
顶部