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 ...
随机推荐
- @Required @Autowired @Resource注解详解
一.@Required注解用于检查特定的属性是否设置 1.RequiredAnnotationBeanPostProcessor 为该注解的处理器,即bean后置处理器,检查所有带有该解的bean属性 ...
- nfs挂在内核出错 T T *** ERROR: Cannot umount
今天在U-boot挂载nfs内核是出现如下错误,网上查了解决方案. SOCFPGA_CYCLONE5 # nfs 20000 192.168.0.75:/work/nfs_root/uImageWai ...
- Linux高级使用功能
1.磁盘管理 LVM 对磁盘的管理,可以拉伸分区的大小而不用格式化 2.网络管理 Iptables 对网络的端口进行管理,放行禁用 3.服务器 apache.nigix html静态的服务器 nigi ...
- 对Native App与Web App的一些思考
前言 Native App:C/S架构,使用原生技术(Java/Objective-C/Swift)实现. Web App:B/S架构,使用浏览器技术来实现,广义上也包括phoneGap以及DP正在尝 ...
- OpenGL: 渲染管线理论
http://blog.csdn.net/augusdi/article/details/19934463 学习着色器,并理解着色器的工作机制,就要对OpenGL的固定功能管线有深入的了解. 首先要知 ...
- Docker学习总结之docker介绍
About Docker 以下均翻译自Docker官方文档 ,转载请注明:Vikings翻译 Develop, Ship and Run Any Application, Anywhere Docke ...
- Flex4 自定义分页组件
自己写的Flex4分页组件,去伪存真,只实现基本的分页功能,数据过滤神马的都不应该是分页组件干的活,有呆毛才有真相: [源代码下载] Flex自从转手给Apache后人气急跌,本人也很捉鸡,尽管Apa ...
- nginx 代理配置文件实例
安装NGINX前要先安装PCRE正则表达式库: ./configure --prefix=/usr/local/pcre 出现以下错误 (一般./configure即可, 笔者这里是直接./conf ...
- C++ Namespace 详解
命名空间的定义格式为:(取自C++标准文档) named-namespace-definition: namespace identifier { namespace-body } unnamed-n ...
- Anaconda日志
https://fedoraproject.org/wiki/Anaconda/Logging Anaconda日志 centos7 anaconda安装日志目录 /var/log/anaconda ...