第一次接触“调用约定”这个概念居然是写了 N 年 VFP 程序之后。
X# 的官方文档中,对调用约定的解释是这样的:调用约定是非托管世界的东西。它们描述了调用函数或方法时应如何传递参数,还描述了被调用函数/方法返回时由谁负责调整堆栈。
首先要理解什么是托管和非托管。
AI 是这样回答大致是这样的:托管是由 .NET运行时(CLR)管理的;非托管是直接运行在操作系统上的。
对于 X# 来说,“对于 “正常的” 托管代码,你实际上只需要处理两种调用约定:1. 对于未类型方法,编译器使用 CLIPPER 调用约定;2.对于类型化方法,编译器在 STRICT 和 PASCAL 之间没有区别。它们都产生相同的代码”
好吧,至少我要理解什么是 Clipper 调用约定,什么是 Strict 调用约定,什么是 Pascal 调用约定。
按照《第二章 X# 的历史渊源及其理念》的内容和 X# 中文档的说明,Clipper 调用约定“是 Xbase 世界中的一种特殊调用约定,在 Xbase 世界中,函数的参数(从技术上讲)都是可选的,而且可以传递比声明参数更多的值。”。至于这个名称的由来,我猜测大概是由此而来:1985 年“Nantucket 发布第一款 dBase 编译器 Clipper 1.0”。
VFP 是 Xbase 世界的一员,因此,按照概念描述和在 VFP 中的经验,所有和 VFP 语法一致的函数/方法都使用的是 Clipper 调用约定,就像下面的这样:
Function foo(a, b, c)
* 一些逻辑代码
Endfunc
函数没有返回类型,参数也未指定类型。这符合 VFP9 帮助中对 Function 命令的第一种语法定义。
但是,其中还有另一种语法定义:
FUNCTION FunctionName( [ parameter1 [ AS para1type ][ ,parameter2 [ AS para2type ] ],...] ) [ AS returntype ]
Commands
[ RETURN [ eExpression ] ]
[ENDFUNC]
在 VFP 中,这种语法可能是为了使 VFP 看上去像是强类型语言,但是在 X# 中,按照官方文档的描述,这应该算是使用了 Strict 调用约定。因此,Clipper 调用约定和 Strict 调用约定的区别跃然纸上。
对于 Pascal 调用约定,X# 的官方文档是这样描述的:这种调用约定在 Pascal 的世界里被广泛使用。它看起来很像 STRICT 调用约定......在 C/C++ 中,这被称为 __stdcall 调用约定。Windows API 中的大多数函数都使用这种调用约定。
至此,对这个概念基本上是了解了。如果在构建项目时看到与此相关的错误信息,也知道该如何修改代码了:)
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有