大家好,我是小周,今天的教程是指导如果使用tiptop来对接windows平台下的dll(动态连接库)去扩充tiptop的功能,Genero 4js公司明确表示4GL语言是支持C和JAVA语言对接的,但是通过单一的语言对接,基本功能有限,所以Genero 4GL提供了和windows dll的对接,这样tiptop可以在客户机通过GDC去调用DLL去完成更多的事情(例如打开QQ,屏幕截图实时聊天等功能)。
下面我们来做一个简单的功能,用户只需要在tiptop界面点击按钮,通过DLL去获得客户机的IP信息(虽然tiptop是能够实现这个功能,但是本次是使用dll去完成),再实时传送给tiptop,再由tiptop去写入数据库保存,这样就可以知道用户的IP地址了。
【测试环境要求】:GDC2.X版本
DLL版本,WIN32 dll ,MFC标准的DLL目前测试不过
DLL编写平台:VISUAL C++ 6.0
【效果如下图】
效果一:只弹出一个窗口代表DLL已经开始工作
效果二:DLL读取计算机名,并传回给TIPTOP显示,本次不显示这个对话框
效果三:DLL读取计算机IP,弹出对话框,并回传给TIPTOP
【首先来编写一个DLL文件】
打开VC 6.0
新建一个DLL工程
找到头文件,看看以下代码申明需要遵循4GL的标准,用于传入和传出的参数必须是一个结构体,我们来申明这个结构体,不要申明其他类型的数据。如下图
#include <stdio.h> struct frontEndInterface { short (* getParamCount) (); short (* getReturnCount) (); void ( * popInteger) (long & , short & ); void ( * pushInteger) (const long , short ); void ( * popString) (char *, short &, short &); void ( * pushString) (const char *,short , short ); void ( * getFrontEndEnv) (const char *, char *,short&); void ( * popWString) (wchar_t *, short &,short &); void ( * pushWString) (const wchar_t*,short,short); }; extern "C" __declspec(dllexport) void finalize(); extern "C" __declspec(dllexport) int makeSum(const frontEndInterface &fx); extern "C" __declspec(dllexport) int Gethostname(const frontEndInterface &fx); extern "C" __declspec(dllexport) int Gettime(const frontEndInterface &fx);
看看具体的函数怎么写,具体的功能大家可以去写的更高大上点,本次就简单的写两个功能来演示:
【上代码】
#include "Mdll.h" #include <stdio.h> #include <malloc.h> #include <string.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib,"ws2_32.lib") void initialize() { //初始化 } void finalize() { //当DLL卸载的时候要做什么 } int makeSum(const struct frontEndInterface &fx) { //获得两个数相加等于几 //这个参数用于返回给tiotop返回执行的结果 short status = -1; // 判断传入的参数对不对,tiptop里传入的参数必须和这个一致,也就是tiptop中没办法去判断 //必须使用几个参数,这里就需要判断参数的个数是否是需要的2个 if (fx.getParamCount() == 2 && fx.getReturnCount() == 2) { long param1, param2; short isNull1, isNull2; //复制到DLL的堆栈 fx.popInteger(param2, isNull2); fx.popInteger(param1, isNull1); if (!isNull1 && !isNull2) { // 计算两个结果的答案,也就是参数A+参数B long sum = param1 + param2; char msg[255]; sprintf(msg, "%d + %d = %d", param1, param2, sum); // 把答案COPY到GDC的堆栈 fx.pushInteger(sum, 0); fx.pushString(msg, strlen(msg), 0); // 成功就返回0 status = 0; } } return status; //所有函数都要返回一个0或者1让TIPTOP接收 } int Gethostname(const struct frontEndInterface &fx) { short status = -1; WSADATA wsadata; WORD dwVersionRequested; int err=WSAStartup(dwVersionRequested,&wsadata); char hostname[255]; if(gethostname(hostname,128)==0) { // 要干点啥?哈哈 //可以MessageBox显示,这里先去掉,直接返回给TIOTIOP显示 } if (fx.getParamCount() == 0 && fx.getReturnCount() == 1) { fx.pushString(hostname, strlen(hostname), 0);//将计算机名放到结构体中供GDC status = 0; } return status; } int Gettime(const struct frontEndInterface &fx) { short status = -1; //未测试过,获得计算机时间 SYSTEMTIME systime; GetLocalTime(&systime); char msg[255]; if (fx.getParamCount() == 0 && fx.getReturnCount() == 1) { sprintf(msg, "%s年%s月%s日 %s:%s:%s",systime.wYear,systime.wMonth,systime.wDay,systime.wHour,systime.wMinute,systime.wSecond); fx.pushString(msg, strlen(msg), 0); status = 0; } return status; }
编译成DLL 文件,找到DEBUG 文件下的这个DLL文件,放到GDC.exe文件下即可
【tiptop中如何操作】
FUNCTION for_dll() DEFINE a,b,c INTEGER DEFINE msg STRING DEFINE res STRING #在tiptop中调用DLL,注意:a,b两个是传入的参数,c,rec是传出的参数 #传入1,3两个整数,通过DLL计算出两个数的和再传出 LET a=1 LET b=3 CALL ui.Interface.frontCall( "Mdll", "makeSum", [a,b], [c,res]) DISPLAY res #res为显示两个数相加的公式:"a+b=" DISPLAY c #c为DLL计算的结果 #调用DLL去获得计算机名字,此时不需要参传入,传出一个结果 CALL ui.Interface.frontCall( "Mdll", "Gethostname", [], [res]) DISPLAY res #传回的结果 CALL FGL_WINMESSAGE("ip", res, "stop") #以对话框显示 END FUNCTION
看看我们的结果:
CALL ui.Interface.frontCall( "Mdll", "makeSum",[a,b], [c,res])结果:
CALL ui.Interface.frontCall( "Mdll","Gethostname", [], [res])结果:
到此,我们就按照此方法写了一个DLL扩展
需要注意的问题:
一、DLL在加载到GDC后不手动卸载就会一直存在,直到GDC退出
二、不管什么DLL扩展,如果需要GDC调用,必须申明一个结构体用于在堆栈中读值,因为windows限定了内存读取方式,DLL是无法直接操作和访问GDC的数据
三、UNIX系统中,可以编写.SO文件去扩展
好啦,大家可以加我 QQ 来一起交流: 123523507 ,大家一起共同学习共同交流