作者:瓜哥,网名木瓜,myfll(通用扩展库)作者,很多人都得益于他的FLL类库,自myfll之后,他又做了myimg(图像库),foxjson(json解析库),fws(CGI库),是位名副其实的技术大拿,猫猫也在瓜哥的帮助下受益良多。现在瓜哥也在狐友会社群里面活跃,社群每月直播分享会即将启动。
1.使用向导创建win32项目,为了跟vc6区分,这个放在了D盘
这一步要选择类型为dll,空项目
然后再项目上点右键添加一个代码文件:
把pro_ext.h 和winapims.lib两个文件拷到main.cpp所在位置的lib下(方便把自己的代码跟库区分)
然后把代码复制过来,然后修改项目配置:
同样,也要修改release的版本的配置
另外,VS2008以上版本的调试,需要手动指定,如下图: 这里可以点右边的箭头找到VFP9.exe的位置
此时,配置完成,可以按F5直接运行开始调试,在要需要设置断点的代码按下F9,运行到这里就会转到调试状态。
VS2015生成发行版本,同样是生成->批生成,选择x86的release版本即可
最终VS2015的项目结构如下
与VC6的目录结构不同,多了一层项目文件夹 其他版本其实都差不多,可以参照这两个版本的配置。
创建FLL项目总结: 1.创建标准的DLL空工程 2.复制VFP两个文件到自己的工程(实际上如果你熟练使用后,可以把头文件和库文件复制到VC默认的include和lib文件夹,这样不用每个项目去复制了。) 3.修改配置,关键是修改动态连接C运行库 /MD和 调用约定 __fastcall 4.修改调试的方式,即默认启动VFP,在VFP里我们手动调用DLL
六.用一个完整功能函数进一步了解FLL开发 上面只是FLL基本框架,代码部分需要学习C/C 语法才可以,不明白的地方就网上搜一下。
FLL的核心是需要一个全局变量 _FoxTable ,它在pro_ext.h中定义,winapims.lib中声明,需要你自己编写它的实体,
FoxTable的定义如下:
这个结构体声明了你这个FLL有多少个函数,函数的地址在哪里,即FoxInfo结构
所以,在这个代码上面,定义了FoxInfo数组:
FoxInfo的定义如下:
funcName:vfp调用时的函数名字 function: C中的函数地址(函数名) parmCount:参数的个数 parmTypes:每个参数的类型 对于这些更加详细的介绍,可以参阅VFP的帮助文档:
能够被VFP调用的C函数,标准格式如下:
代码语言:javascript复制void 函数名(ParamBlk* parm)
{
}
函数需要接收一个ParamBlk类型的指针,本身不能有返回值,返回VFP有特定的几个函数_RetXXX开头的函数,在头文件中有声明:
ParamBlk是一个变长数组结构体
其中pCount指明了参数有几个,即FoxParameter p[]多少个 FoxParameter是一个联合体,VFP中以值传递时,我们需要用Value访问,如果VFP是以引用传递时,需要用Locator访问
下面以再添加一个函数为例演示接收参数和返回结果。 我们在VFP端输入一个整型参数和一个字符参数,FLL返回两者连接后的结果: VFP调用为 IntAndStr(123,”test”) 返回结果是 123test
1.先添加一个C函数和函数列表
这里演示了VFP调用名字跟C中函数名不同的用法,因为C的函数名最终都编译为地址,用什么名字都无所谓,FoxInfo结构第一个即VFP端函数名字,第二个是C端的函数名,第三个2 表示此函数接收两个参数,最后一个“IC”分别表示,第一个参数为I只接收整型,第二个参数C只接受字符型,如果你在VFP端传递了不符合要求的类型,在VFP端就会报错,参数错误。
现在来写具体代码:
代码语言:javascript复制void test2(ParamBlk* parm)
{
//获取整型参数
int p1=parm->p[0].val.ev_long;
//获取字符型参数
int len=parm->p[1].val.ev_length;//字符串参数的长度
//C的字符串是以0结尾,而VFP的字符串并不一定是0结果,所以要处理下
//先设置长度以容纳0,然后修改
_SetHandSize(parm->p[1].val.ev_handle,len 1);
char* p2=(char*)_HandToPtr(parm->p[1].val.ev_handle);//获取字符串参数的指针
p2[len]='