Delphi和Android Studio混合开发(二)FMX项目和Android混合开发

Delphi开发Android程序非常快,拖拖拉拉几下子就可以开发出一个Android程序,而且还可以随意输出成Windows,Mac,Linux,iOS上面。

但是因为Delphi和Android Studio开发的的Android APP还是有点区别的,和C++开发Android APP类似,Delphi是编译成SO然后由Java代码中LoadLibrary加载,所有界面都是FMX自绘制的。Delphi IDE只能集成.jar,无法集成.aar,集成.aar要解压开,拿出里面的.jar,.so以及资源文件等手动集成进去。因为没有gradle也没有继承maven库上代码的功能,只能把m[……]

继续阅读

发表在 Android, APP, Delphi, 未分类 | 标签为 , , , , , | Delphi和Android Studio混合开发(二)FMX项目和Android混合开发已关闭评论

Delphi和Android Studio混合开发(一)Delphi开发标准.SO给Android Studio用

Delphi自从开始跨平台,支持Windows,Linux,Mac,iOS,Android以后,玩法就多了很多。

实际上Delphi在开发任何平台的代码的时候都是编译成原生的Native Code,在Android平台,Delphi的代码和C++一样是被编译为SO(Linux,Unix上的动态链接库)文件,由一小段JVM代码直接加载.SO,引入原生代码。

这篇文章介绍的是用Delphi开发一个JNI形式的SO给Android调用,好处是SO是ARM的机器码,执行效率比JVM的执行效率要高,而且SO是原生代码并不像Java字节码那样容易被反编译,另外还有一个Delphi编译器产生的代[……]

继续阅读

发表在 Android, APP, Delphi, 未分类 | 标签为 , , , , | Delphi和Android Studio混合开发(一)Delphi开发标准.SO给Android Studio用已关闭评论

Delphi12的一个数据库问题

我身边的朋友都是第一时间更新Delphi的版本。

他把服务端程序由Delphi11更新到最新的Delphi12,发现DBExpress的用FieldByName().asBytes读取Blob型数据有问题,读的不正确。

FieldByName().asString读到的字符串也不正确

经过跟他的排查发现Delphi12的数据库在64位的时候读取Blob的时候会出问题。

主要原因是Delphi12的Classes文件里面把TStream.ReadBuffer的64位实现重写,发生了变化。

下面是Delphi11的TStream.ReadBuffer

下面[……]

继续阅读

发表在 未分类 | 标签为 , | Delphi12的一个数据库问题已关闭评论

给Delphi高版本添加类似Kotlin的for的功能

前几天在盒子的帖子上讨论Delphi11的特性,一个朋友说希望有for in 0..100这种类似kotlin的循环语法。

随便指出了可以变相实现for in [0..100]即可,结果有其他朋友验证了,这种写法在DelphiXE1之前的版本是可以的,在高版本Delphi上实际上被认为是集合,那么就不能超过255个元素,无法实用。

好在高版本的Delphi的For in是通过数据类型有一个GetEnumerator方法返回枚举器来实现的,一些简单数组之类的靠编译器自动处理的。

那么就可以变相实现这个功能了。

这就变相的实现了仿kotlin这种直接for[……]

继续阅读

发表在 未分类 | 标签为 | 给Delphi高版本添加类似Kotlin的for的功能已关闭评论

Android,保活,复活,防杀

从Android5到Android11都通用。
这是在我的Mate40Pro(Android10)上面的效果

[……]

继续阅读

发表在 Android, APP, Delphi, 未分类 | 标签为 , , , | 2条评论

Managed Record的使用一则

其实Managed Record有很多方便使用的场景。
比如下面的就是把TStringBuilder由Class改成了Managed Record。好处就是不再需要释放了。[……]

继续阅读

发表在 Delphi | 标签为 , , | Managed Record的使用一则已关闭评论

Delphi Managed Record的一个不方便的地方

使用的时候还要
var a : TMyRecord := TMyRecord.create(1);
实际上既有constructor,又有Initialize,是有歧义的,完全可以合并。
变成如下这种方式:
class operator Initialize(out Dest: TMyRecord, 各种构造的参数);
比如
class operator Initialize(out Dest: TMyRecord, v : Integer);
使用的时候就可以非常简洁了。
var a : TMyRecord(1);[……]

继续阅读

发表在 Delphi | 标签为 , | Delphi Managed Record的一个不方便的地方已关闭评论

Delphi10.4托管记录(Managed Record)产生的机器代码分析

只分析了Delphi Windows平台X86,X64上的代码,ARM平台和Linux平台基于是LLVM编译器的,没有分析。

Delphi 10.4

VC2015

VC的代码之所以加了GetTickCount,Sleep是因为VC的编译器极其智能,Release版本的时候如果函数为空会直接优化掉。

先看X86版本Delphi的代码(代码优化是否勾选,产生的代码没有区别,也就是这块Debug和Release版本是一样的)

十分的啰嗦,基本可以理解成是加了一大堆的Try Finally。懒得要死。

再看VC X86 Debug版本的代码

还算干脆利索,非常直接。
再看VC X[……]

继续阅读

发表在 Delphi | 标签为 | 4条评论

Delphi 10.4 的期待和不足

Delphi10.4发布在即,看了许多特性宣传,最值得期待的就是托管记录。
最开始Delphi的结构体支持操作符重载,就很兴奋,想自己封装算法库,自己封装智能指针。
比如自己实现string,自己实现BigInt之类的。结果发现record虽然支持了操作符重载,但是不能自动初始化和反初始化。导致一些事情很难做,比如string我要默认是”,BigInt默认是0等等。
十几年前就建议增加初始化和反初始化的操作符重载,结果人家回了句话十几年都在没动静。
好在这次总算是增加了这方面的支持,但是我觉得还没做全。

想要实现类似C++的智能指针还缺个重要的操作符重载,就是.或者->(Delphi里面是^[……]

继续阅读

发表在 Delphi | 8条评论

CPP各个操作系统和平台的宏定义

#if TARGET_OS_MAC
#if TARGET_OS_IPHONE
#if TARGET_IPHONE_SIMULATOR
#if TARGET_OS_EMBEDDED

#ifdef __ANDROID__

#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
#if defined(__IPHONE_OS_MIN_VERSION_REQUIRED)

//Windows
#ifdef WIN32
#ifdef _WIN32
//64位Window[……]

继续阅读

发表在 CPP | 标签为 , , , | 103条评论