Delphi For Android 开发笔记-附:如何Delphi中同时实现Windows、Android版的GetModuleFileName函数
在Windows中开发DLL时,经常会需要获取当前DLL所在目录以便读取同目录下的其他文件,而目前Delphi在开发android时,其实没多大必要获取,因为整个工程只有一个so文件,而这个so文件也可以通过引用System.IOUtils,再使用TPath.GetLibraryPath()即可。
不过有时候我们确实需要用到类似Windows中GetModuleFileName和GetModuleHandle等函数, 这些我们应该如何在android中去实现呢?
1.linux中的进程管理/proc/[PID]/XXXX
在linux中乃至各种遵循posix的unix类系统,均可以在/proc/路径下面得到系统各种进程的相关信息,因此下面的代码在MacOS和iOS中其实是可以通用的,因为Posix标准就是为了可移植而定义的,对于开发人员来说,用一套代码走遍所有系统是非常高兴的事,而进程各个模块的信息则在maps文件中。
2.实现android版的GetModuleFileName
下面各种版本的实现代码:
2.1 FreePascal 代码
//可支持android和linux
uses
{$IFDEF FPC}
{$IFDEF UNIX}
//BaseUnix, Unix,
dl;
{$ENDIF}
{$ENDIF}
9 type
10 HMODULE = Cardinal;
{$IFDEF FPC}
{$IFDEF UNIX}
function GetModuleFileName(hLib: HMODULE):string;
var
dlinfo: dl_info;
IsLib: Boolean;
begin
if hLib= then
hLib := HMODULE(@GetModuleFileName); dladdr(Pointer(hLib), @dlinfo);
Result:=string(dlinfo.dli_fname);
end;
{$ENDIF}
{$ENDIF}
2.2 delphi XE7 代码
//支持android, MacOS没测试,可能会有问题但原理是正确的
uses
{$IFDEF POSIX}
Posix.Base,
Posix.Dlfcn,
{$ENDIF}
Classes, SysUtils; type
HMODULE = Cardinal; {$IFNDEF FPC}
{$IFDEF ANDROID}
//Posix.Dlfcn中android版本的dladdr只返回模块名称,不返回全路径
//因此需要自己实现dladdr
threadvar
_ModuleName: MarshaledAString; function dladdr(Lib: pointer; info: Pdl_info): Longint; cdecl;
var
F: Text;
s, ss, curnode: string;
a1, a2, curbase: UIntPtr;
//i: longint;
p, pp: PByte;
M: TMarshaller;
begin
Result:=;
_ModuleName:='';
if info = nil then
exit;
curbase:=;
curnode:='';
Assign(F, '/proc/self/maps');
Reset(F);
if IoResult <> then
exit;
while not Eof(F) do
begin
// Read the address range info
ReadLn(F, ss);
p:=PByte(M.AsAnsi(ss, CP_UTF8).ToPointer);
// Starting address
pp:=p;
while not (p^ in [Byte(Ord('-')), Byte(Ord(#))]) do
Inc(p);
p^ := Byte(Ord(#)); s := UTF8ToString(MarshaledAString(pp));
a1 := StrToIntDef('$'+s, );
if a1 > then
begin
// Ending address
Inc(p);
pp:=p;
while p^ > Byte(Ord(' ')) do
Inc(p);
p^ := Byte(Ord(#)); s := UTF8ToString(MarshaledAString(pp));
a2 := StrToIntDef('$'+s, ); if a2 > then
begin
while p^ <= Byte(Ord(' ')) do Inc(p); // Whitespace
while p^ > Byte(Ord(' ')) do Inc(p); // Skip perms
while p^ <= Byte(Ord(' ')) do Inc(p); // Whitespace
while p^ > Byte(Ord(' ')) do Inc(p); // Skip offset
while p^ <= Byte(Ord(' ')) do Inc(p); // Whitespace
while p^ > Byte(Ord(' ')) do Inc(p); // Skip dev
while p^ <= Byte(Ord(' ')) do Inc(p); // Whitespace
// inode
pp:=p;
while p^ > Byte(Ord(' ')) do
Inc(p);
p^ := Byte(Ord(#)); s := UTF8ToString(MarshaledAString(pp)); if s <> '' then
begin
if s <> curnode then
begin
curnode:=s;
curbase:=a1;
end; if (UIntPtr(Lib) >= a1) and (UIntPtr(Lib) < a2) then
begin
while p^ <= Byte(Ord(' ')) do Inc(p); // Whitespace
// File name
if p^ = Byte(Ord('/')) then
begin
_ModuleName:=MarshaledAString(p);
info^.dli_fname:=MarshaledAString(_ModuleName);
info^.dli_fbase:=pointer(curbase);
info^.dli_sname:=nil;
info^.dli_saddr:=nil;
Result:=;
end;
break;
end;
end;
end;
end;
end;
Close(F);
end;
{$ELSE}
function dladdr(Lib: pointer; info: Pdl_info): Longint; cdecl;
begin
Result := Posix.Dlfcn.dladdr(UIntPtr(Lib), info^);
end;
{$ENDIF}
{$ENDIF} {$IFDEF POSIX}
function GetModuleFileName(hLib: HMODULE):string;
var
dlinfo: dl_info;
IsLib: Boolean;
begin
if hLib= then
hLib := HMODULE(@GetModuleFileName); dladdr(pointer(hLib), @dlinfo);
Result := UTF8ToString(dlinfo.dli_fname);
end;
{$ENDIF}
3. 实现android版的GetModuleHandle
有了上面的dladdr实现,其实GetModuleHandle只是由原来通过地址信息获得路径名,逆处理为由路径名获取地址信息,而首地址即使so加载到内存后的句柄。
Delphi For Android 开发笔记-附:如何Delphi中同时实现Windows、Android版的GetModuleFileName函数的更多相关文章
- 《ArcGIS Runtime SDK for Android开发笔记》——(4)、基于Android Studio构建ArcGIS Android开发环境
1.前言 2015年1月15日,发布ArcGIS Runtime SDK for Android v10.2.5版本.从该版本开始默认支持android studio开发环境,示例代码的默认开发环境也 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)(转)
1.前言 在上一篇的内容里我们介绍了基于Android Studio构建ArcGIS Runtime SDK for Android开发环境的基本流程,流程中我们采用的是基于Gradle的构建方式,在 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(6)、基于Android Studio的ArcGIS Android工程结构解析
1.前言 Android Studio 是第一个Google官方的 Android 开发环境.其他工具,例如 Eclipse,在 Android Studio 发布之前已经有了大规模的使用.为了帮助开 ...
- 【转】Android开发笔记(序)写在前面的目录
原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...
- 【转】Android开发笔记——圆角和边框们
原文地址:http://blog.xianqu.org/2012/04/android-borders-and-radius-corners/ Android开发笔记——圆角和边框们 在做Androi ...
- 《ArcGIS Runtime SDK for Android开发笔记》
开发笔记之基础教程 ArcGIS Runtime SDK for Android 各版本下载地址 <ArcGIS Runtime SDK for Android开发笔记>——(1).And ...
- [APP] Android 开发笔记 003-使用Ant Release 打包与keystore加密说明
接上节 [APP] Android 开发笔记 002 5. 使用ant release 打包 1)制作 密钥文件 release.keystore (*.keystore) keytool -genk ...
- Android开发笔记:打包数据库
对于数据比较多的控制一般会加入SQLite数据库进行数据存储,在打包时这些数据库是不自动打包到apk中的,如何创建数据库呢 方法1:将创建数据库的sql语句在SQLiteHelper继承类中实现,在第 ...
- Android开发笔记--hello world 和目录结构
原文:Android开发笔记--hello world 和目录结构 每接触一个新东西 都有一个hello world的例子. 1.新建项目 2.配置AVD AVD 没有要新建个,如果不能创建 运行SD ...
随机推荐
- SQL(Oracle)
http://blog.csdn.net/winter13292/article/details/7011377 SQL 对大小写不敏感! 在 SQL 中增加 HAVING 子句原因是,WHERE ...
- Spring-MongoDB简单操作
1.简单的配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http: ...
- Android中Context详解 ---- 你所不知道的Context
转自:http://blog.csdn.net/qinjuning/article/details/7310620Android中Context详解 ---- 你所不知道的Context 大家好, ...
- 菜鸟-手把手教你把Acegi应用到实际项目中(8)-扩展UserDetailsService接口
一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...
- 菜鸟-手把手教你把Acegi应用到实际项目中(3)
这一节我们将要了解的是AnonymousProcessingFilter.RememberMeProcessingFilter和LogoutFilter三个过滤器. 1.AnonymousProces ...
- PostMan入门使用教程
最近需要测试产品中的REST API,无意中发现了PostMan这个chrome插件,把玩了一下,发现postman秉承了一贯以来google工具强大,易用的特质.独乐乐不如众乐乐,特此共享出来给大伙 ...
- kubernetes源码解析---- apiserver路由构建解析(1)
kubernetes源码解析---- apiserver路由构建解析(1) apiserver作为k8s集群的唯一入口,内部主要实现了两个功能,一个是请求的路由和处理,简单说就是监听一个端口,把接收到 ...
- autoit UIA获取Listview的信息
#include "CUIAutomation2.au3" Opt( ) Global $oUIAutomation MainFunc() Func MainFunc() ; Be ...
- 【PL/SQL练习】显式游标
cursor --------需要用户先定义,在select时,可以用于处理多行记录 1.declare 声明一个游标 2.open cursor (隐式游标自动open) 3.fetch curs ...
- ctags 文章
http://blog.csdn.net/wuziqi4/article/details/1709722