最进想将Pascal脚本引擎在.Net环境下能够使用,不仅仅是调用,脚本环境还需调.Net宿主程序的一些函数(注册回调函数)
故对Delphi与.Net交叉调用准备作一系列研究 这是最第一步基本数据类型一致性测试
相关代码 InteropTest.rar
delphi 基本类型:
- 单字节 Boolean ShortInt Byte
- 双字节 SmallInt Word WideChar
- 四字节 Integer LongInt LongWord Cardinal Single
- 八字节 Int64 Comp Double Real
- 高精度 Currency(8字节) Extended(10字节)
.Net 基本类型
- 单字节 Boolean Byte SByte
- 双字节 Int16 UInt16 Char
- 四字节 Int32 UInt32 Single
- 八字节 Int64 UInt64 Double
- 高精度 Decimal
Decimal 值类型表示从正 79,228,162,514,264,337,593,543,950,335 到负 79,228,162,514,264,337,593,543,950,335 之间的十进制数。Decimal 值类型适用于要求使用大量有效的整数及小数位数并且没有舍入错误的财务计算。
十进制数是由符号、数值和比例因子组成的浮点值,数值的每一位的范围都是 0 到 9,比例因子指示分隔数值的整数和小数部分的浮点小数点的位置。
Decimal 值的二进制表示形式由 1 位符号、96 位整数以及比例因子组成,比例因子用作 96 位整数的除数并指定整数的哪一部分为小数。比例因子隐式地定为数字 10 的幂,指数范围从 0 到 28。因此,Decimal 值的二进制表示形式为:((-296 到 296) / 10(0 到 28)),其中 -296-1 等于 MinValue,而 296-1 等于 MaxValue。
比例因子还保留 Decimal 数字中的所有尾随零。在算术或比较运算中,尾随零并不影响 Decimal 数字的值。但是,如果应用了正确的格式字符串,则可由 ToString 方法显示尾随零。
测试后得出结论如下:
后来增加了对Boolean类型的更深入的测试得出结论如下:
- Delphi的Boolean值传给.Net时完全正确
- .Net的值无论传True或False Delphi都得到True值
- 经过Debug 查看汇编代码得知
Delphi
Boolean = Byte true($01) false($00)
ByteBool = Byte true($ff) false($00)
WordBool = Word true($ffff) false($0000)
LongBool = DWord true($ffffffff) false($00000000)
.Net
Boolean = DWord true(1) false(0)
procedure ProcedureInterop; stdcall;
function FunctionInterop: Integer; stdcall;
// size 1 B True False
function BooleanInterop(Size: Integer; InParam: Boolean; var OutParam: Boolean): Boolean; stdcall;
// size 1 -128~127
function ShortIntInterop(Size: Integer; InParam: ShortInt; var OutParam: ShortInt): ShortInt; stdcall;
// size 1 u 0~255
function ByteInterop(Size: Integer; InParam: Byte; var OutParam: Byte): Byte; stdcall;
// size 2 -32,768~32,767
function SmallIntInterop(Size: Integer; InParam: SmallInt; var OutParam: SmallInt): SmallInt; stdcall;
// size 2 u 0~65,536
function WordInterop(Size: Integer; InParam: Word; var OutParam: Word): Word; stdcall;
function WideCharInterop(Size: Integer; InParam: WideChar; var OutParam: WideChar): WideChar; stdcall;
// size 4 -2,147,483,648~2,147,483,647
function IntegerInterop(Size: Integer; InParam: Integer; var OutParam: Integer): Integer; stdcall;
function LongIntInterop(Size: Integer; InParam: LongInt; var OutParam: LongInt): LongInt; stdcall;
// size 4 u 0~4,294,967,295
function LongWordInterop(Size: Integer; InParam: LongWord; var OutParam: LongWord): LongWord; stdcall;
function CardinalInterop(Size: Integer; InParam: Cardinal; var OutParam: Cardinal): Cardinal; stdcall;
// size 4 f 1.5*10(-45)~3.4*(38)
function SingleInterop(Size: Integer; InParam: Single; var OutParam: Single): Single; stdcall;
// size 8 -9,223,372,036,854,775,808~9,223,372,036,854,775,807
function Int64Interop(Size: Integer; InParam: Int64; var OutParam: Int64): Int64; stdcall;
function CompInterop(Size: Integer; InParam: Comp; var OutParam: Comp): Comp; stdcall;
// size 8 d 5.0*10(-324)~1.7*10(308)
function DoubleInterop(Size: Integer; InParam: Double; var OutParam: Double): Double; stdcall;
function RealInterop(Size: Integer; InParam: Real; var OutParam: Real): Real; stdcall;
// size 8 c -922,337,203,685,477.5808~922,337,203,685,477.5807
function CurrencyInterop(Size: Integer; InParam: Currency; var OutParam: Currency): Currency; stdcall;
// size 10 e 3.4*10(-4932)~1.1*10(4932)
function ExtendedInterop(Size: Integer; InParam: Extended; var OutParam: Extended): Extended; stdcall;
// 16 v
function VariantInterop(Size: Integer; InParam: Variant; var OutParam: Variant): Variant; stdcall;
对应.net2.0类型定义
using ShortInt = System.SByte;
using SmallInt = System.Int16;
using Word = System.UInt16;
using WideChar = System.Char;
using Integer = System.Int32;
using LongInt = System.Int32;
using LongWord = System.UInt32;
using Cardinal = System.UInt32;
using Comp = System.Int64;
using Real = System.Double;
using Currency = System.Decimal;
using Extended = System.Decimal;
using Variant = System.Object;
namespace AIO.Win32.PascalAIO
{
public class InteropService
{
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void ProcedureInterop();
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 FunctionInterop();
// size 1 B True False
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Boolean BooleanInterop(Int32 Size, Boolean InParam, out Boolean OutParam);
// size 1 -128~127
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern ShortInt ShortIntInterop(Int32 Size, ShortInt InParam, out ShortInt OutParam);
// size 1 u 0~255
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Byte ByteInterop(Int32 Size, Byte InParam, out Byte OutParam);
// size 2 -32,768~32,767
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern SmallInt SmallIntInterop(Int32 Size, SmallInt InParam, out SmallInt OutParam);
// size 2 u 0~65,536
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Word WordInterop(Int32 Size, Word InParam, out Word OutParam);
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern WideChar WideCharInterop(Int32 Size, WideChar InParam, out WideChar OutParam);
// size 4 -2,147,483,648~2,147,483,647
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Integer IntegerInterop(Int32 Size, Integer InParam, out Integer OutParam);
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern LongInt LongIntInterop(Int32 Size, LongInt InParam, out LongInt OutParam);
// size 4 u 0~4,294,967,295
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern LongWord LongWordInterop(Int32 Size, LongWord InParam, out LongWord OutParam);
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Cardinal CardinalInterop(Int32 Size, Cardinal InParam, out Cardinal OutParam);
// size 4 f 1.5*10( -45)~3.4*( 38)
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Single SingleInterop(Int32 Size, Single InParam, out Single OutParam);
// size 8 -9,223,372,036,854,775,808~9,223,372,036,854,775,807
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Int64 Int64Interop(Int32 Size, Int64 InParam, out Int64 OutParam);
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Comp CompInterop(Int32 Size, Comp InParam, out Comp OutParam);
// size 8 d 5.0*10( -324)~1.7*10( 308)
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Double DoubleInterop(Int32 Size, Double InParam, out Double OutParam);
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Real RealInterop(Int32 Size, Real InParam, out Real OutParam);
// size 8 c -922,337,203,685,477.5808~922,337,203,685,477.5807
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Currency CurrencyInterop(Int32 Size, Currency InParam, out Currency OutParam);
// size 10 e 3.4*10( -4932)~1.1*10( 4932)
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Extended ExtendedInterop(Int32 Size, Extended InParam, out Extended OutParam);
// 16 v
[DllImport("PascalAIO.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Variant VariantInterop(Int32 Size, Variant InParam, out Variant OutParam);
}
}
测试结果如下: