在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函数的更多相关文章

  1. 《ArcGIS Runtime SDK for Android开发笔记》——(4)、基于Android Studio构建ArcGIS Android开发环境

    1.前言 2015年1月15日,发布ArcGIS Runtime SDK for Android v10.2.5版本.从该版本开始默认支持android studio开发环境,示例代码的默认开发环境也 ...

  2. 《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)(转)

    1.前言 在上一篇的内容里我们介绍了基于Android Studio构建ArcGIS Runtime SDK for Android开发环境的基本流程,流程中我们采用的是基于Gradle的构建方式,在 ...

  3. 《ArcGIS Runtime SDK for Android开发笔记》——(6)、基于Android Studio的ArcGIS Android工程结构解析

    1.前言 Android Studio 是第一个Google官方的 Android 开发环境.其他工具,例如 Eclipse,在 Android Studio 发布之前已经有了大规模的使用.为了帮助开 ...

  4. 【转】Android开发笔记(序)写在前面的目录

    原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...

  5. 【转】Android开发笔记——圆角和边框们

    原文地址:http://blog.xianqu.org/2012/04/android-borders-and-radius-corners/ Android开发笔记——圆角和边框们 在做Androi ...

  6. 《ArcGIS Runtime SDK for Android开发笔记》

    开发笔记之基础教程 ArcGIS Runtime SDK for Android 各版本下载地址 <ArcGIS Runtime SDK for Android开发笔记>——(1).And ...

  7. [APP] Android 开发笔记 003-使用Ant Release 打包与keystore加密说明

    接上节 [APP] Android 开发笔记 002 5. 使用ant release 打包 1)制作 密钥文件 release.keystore (*.keystore) keytool -genk ...

  8. Android开发笔记:打包数据库

    对于数据比较多的控制一般会加入SQLite数据库进行数据存储,在打包时这些数据库是不自动打包到apk中的,如何创建数据库呢 方法1:将创建数据库的sql语句在SQLiteHelper继承类中实现,在第 ...

  9. Android开发笔记--hello world 和目录结构

    原文:Android开发笔记--hello world 和目录结构 每接触一个新东西 都有一个hello world的例子. 1.新建项目 2.配置AVD AVD 没有要新建个,如果不能创建 运行SD ...

随机推荐

  1. ARM开发板挂载U盘

    ARM开发板运行Linux系统后,插入U盘,通过串口打印系统识别到U盘如下: 系统识别U盘盘符为sda4 那么需要挂载后才能操作U盘:挂载命令 mount -t vfat /dev/sda4 /mnt ...

  2. regulator

    http://blog.sina.com.cn/s/blog_5e99b41e0101a3ng.html http://blog.sina.com.cn/s/blog_694348b00100n3ip ...

  3. mysql 存储结构

    mysql存储结构:数据库->表->数据 1)管理数据库 增:create database sjk; 删:drop database sjk; 改:alter database sjk; ...

  4. app控件获取之uiautomatorviewer

    初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...

  5. Web自动化框架LazyUI使用手册(1)--框架简介

    作者:cryanimal QQ:164166060 web端自动化简介 web端自动化,即通过自动化的方式,对Web页面施行一系列的仿鼠标键盘操作,以达到对Web页面的功能进行自动化测试的目的. 其一 ...

  6. Drupal8开发教程:认识.info.yml文件

    YAML 文件是新引入的重要项目文件,在 Drupal 8 中,无论是模块.主题还是安装配置文件,都需要 .info.yml 文件来为其存储项目相关的基础信息. 在 Drupal 中,.info.ym ...

  7. 挣值管理(EVT)

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 第二个大计算,根据PV.EV.AC计算出CV.SV.SPI.CPI.ETC.EAC. ...

  8. Java Annotation 机制源码分析与使用

    1 Annotation 1.1 Annotation 概念及作用      1.  概念 An annotation is a form of metadata, that can be added ...

  9. extern 相关

    假如a.h中有 int a=10; t1.cpp和t2.cpp同时include "a.h"则编译不成功,因为a重复定义:如果 a.h中是 static int a=10;则可以, ...

  10. C# 图片旋转360度程序

    这几天开发一个程序,需要将一个图片旋转360度然后每一个角度保存下来.刚开始本来想着是让美工弄的,但是让一个美工手动转360度,她会喷你一脸. using System; using System.C ...