当前位置: 首页 > news >正文

Delphi7通过VB6之COM对象调用FreeBASIC写的DLL功能

 VB6写ActiveX COM组件比较方便,不仅PowerBASIC与VB6兼容性好,Delphi7与VB6兼容性也不错,但二者与FreeBASIC兼容性在字符串处理上差距比较大,FreeBASIC是C化的语言,可直接使用C指令。下面还是以实现MKI/CVI, MKL/CVL, MKS/CVS, MKD/CVD, CRC16为出发点,先说说VB6与FreeBASIC的字符串交互,然后VB6做成ActiveX与Delphi7交互就比较方便了。FreeBASIC和PowerBASIC一样拥有保留字MKI/CVI, MKL/CVL, MKS/CVS, MKD/CVD, 同时还拥有 lang -QB 后几乎QUICK BASIC的全部指令可用。

FreeBASIC写DLL入口出口模板做好的(是个形式需要,没实际内容),下载勇芳的FreeBASIC免安装直接运行,选用DLL模板然后写自己的函数。下面是实现 MKI 的代码,在FreeBASIC里即可用MKI,还有MKShort可用。

FUNCTION myMKI (ByVal Param1 AS Short) AS BSTR EXPORTDIM I AS ShortDIM TString AS STRINGI = 0 : TString = ""' code goes hereFOR I = 2 TO 1 STEP -1TString=TString+RIGHT(("0"+LTRIM(HEX(ASC(MID(MKShort(Param1),I,1))))),2)NEXT IFUNCTION = StringToBStr(TString)
END FUNCTION

Function里 ByVal Param1 as Short,可以接收VB6的Integer,as BSTR是VB6用的字符串格式,CSDN的知识告诉我们它是宽字符,并且字符串前面有4个字节记录了字符串长度,而FreeBASIC里用的字符串是C格式的,接收了VB6整数直接处理没问题,但返回字符串给VB6不能直接返回,缺少四个字节的东西。StringToBSTR是为转换做的函数,函数里没做什么处理,而是用C的oleauto.h里的SysAllocString完成转换的,前面说了,FreeBASIC直接可用C的命令。

再看看MKS,也是用的MKS函数,也同样转换成BSTR返回给VB6。

FUNCTION myMKS (BYVAL Param1 AS SINGLE) As BSTR EXPORTDIM I AS INTEGERDIM TString AS STRINGI=0: TString=""' code goes hereFOR I = 4 TO 1 STEP -1TString=TString+RIGHT(("0"+LTRIM(HEX(ASC(MID(MKS(1.0*Param1),I,1))))),2)NEXT IFUNCTION = StringtoBStr(TString)
END FUNCTION

如果Function里接收VB6字符串,处理后返回给VB6字符串,不仅要StringtoBSTR转换,还要对接收的字符串进行BSTRtoString转换,看下面的代码。

FUNCTION myINSTRU (BYVAL Param1 AS BStr) As BSTR EXPORTDIM LParam1 AS STRINGDIM RETURNSTR AS STRINGRETURNSTR = "UNKNOWN"LParam1 = BStrToString(Param1)SELECT CASE LParam1CASE "VERSION"RETURNSTR = "VERSION 1.00 9AUG2023"CASE "AUTHOR"RETURNSTR = "Mongnewer"END SELECTFUNCTION = StringToBstr(RETURNSTR)
END FUNCTION

BstrTostring的实现稍复杂一些,代码如下:

Function BStrToString(nBStr As BStr) As String  '将VB里的字符串转换为FB里使用的字符串Dim L As Long =Peek(Long,Cast(UInteger,nBStr) -4)Dim ss As String = String(L,0)memcpy StrPtr(ss),nBStr,LFunction = ss
End Function

取得VB6字符串的地址减4然后直接Peek从内存中读出来传送的字符串长度,再造一个这个长度的本地string,再把收到的BSTR的字符考贝到新建的字符之中,这样等长度字符就有了。字符串转换在FreeBASIC里勇芳做了细致的工作,更多更细代码下载开发环境都带齐了。

如果VB6传送前知道字符串长度,或是通过另外的参数同时传送长度值,那处理就更方便了。FreeBASIC可以在函数中定义 ByRef Param1 AS BStr , VB6那边也是ByRef,然后呢,宽字符直接考贝。Dim As String ss = "FreeBASIC One",StrCpyW(Param1, Cast(WString Ptr, StrPtr(ss))), 在VB6里看到字符串会被FreeBASIC改写了。

传送时FreeBASIC有Byref和Byval 类型 ptr指针可用,VB6有Byref和Varptr可用,Delphi有 Pchar等P指针可用,传送地址改写地址数据进行交互还是比较方便的,长度问题最简便的方法是传送时用另外的参数传送长度值。

VB6写ActiveX与上篇《Delphi7通过VB6之COM对象调用PowerBASIC写的DLL功能》博文类似Delphi7通过VB6之COM对象调用PowerBASIC写的DLL功能_Mongnewer的博客-CSDN博客

只是在函数声明时稍做改变

Private Declare Function myMKI Lib "MBFIEEE32FB.dll" Alias "MYMKI@4" (ByVal a As Integer) As String
Private Declare Function myCVI Lib "MBFIEEE32FB.dll" Alias "MYCVI@4" (ByVal b As String) As Integer
Private Declare Function myMKL Lib "MBFIEEE32FB.dll" Alias "MYMKL@4" (ByVal a As Long) As String
Private Declare Function myCVL Lib "MBFIEEE32FB.dll" Alias "MYCVL@4" (ByVal b As String) As Long
Private Declare Function myMKS Lib "MBFIEEE32FB.dll" Alias "MYMKS@4" (ByVal a As Single) As String
Private Declare Function myCVS Lib "MBFIEEE32FB.dll" Alias "MYCVS@4" (ByVal b As String) As Single
Private Declare Function myMKD Lib "MBFIEEE32FB.dll" Alias "MYMKD@8" (ByVal a As Double) As String
Private Declare Function myCVD Lib "MBFIEEE32FB.dll" Alias "MYCVD@4" (ByVal b As String) As Double
Private Declare Function myCRC16 Lib "MBFIEEE32FB.dll" Alias "MYCRC16@4" (ByVal a As String) As String
Private Declare Function myINSTRU Lib "MBFIEEE32FB.dll" Alias "MYINSTRU@4" (ByVal a As String) As String

函数名不变,Lib选的DLL文件变了,然后有个 Alias 名,FreeBASIC编译器会为每个函数加上别名,如果拿不准具体别外,可在终端窗口中 dumpbin /exports mbfieee32fb.dll ,库中的别名就都列出来了。 dumpbin 是装 studio 平台自带的工具,也能单独找到。

因为函数名不变,所以Delphi7调用时除引用的COM不同,其它可以保持不变。

VB6做COM可以粘接PowerBASIC,也可以粘接FreeBASIC,还可以在一个COM下同时粘接 PowerBASIC和FreeBASIC写的DLL,当然,也可以不用COM直连互通。这些东西都挺古老了,就不赘述了。

http://www.lryc.cn/news/120452.html

相关文章:

  • 【Linux 网络】NAT技术——缓解IPv4地址不足
  • Flink 两阶段提交(Two-Phase Commit)协议
  • 【Docker晋升记】No.2 --- Docker工具安装使用、命令行选项及构建、共享和运行容器化应用程序
  • [OnWork.Tools]系列 00-目录
  • Cadvisor+InfluxDB+Grafan+Prometheus(详解)
  • AtcoderABC222场
  • 架构实践方法
  • 点淘的MCN机构申请详细入驻指南!
  • 事务和事务的隔离级别
  • 每日一题 34在排序数组中查找元素的第一个和最后一个位置(二分查找)
  • Spring Boot Admin 环境搭建与基本使用
  • JVM之内存模型
  • 音视频 vs2017配置FFmpeg
  • 【项目管理】PMP备考宝典-第二章《环境》
  • ELK 将数据流转换回常规索引
  • jackson库收发json格式数据和ajax发送json格式的数据
  • ubuntu安装和卸载CLion
  • Petrel解释二维浅地层数据
  • 分布式任务调度平台XXL-JOB使用
  • 自考本科汉语言文学专业真的太难了吗
  • STM32CubeMX之freeRTOS信号量
  • react-spring,一个react的动画库的使用
  • Python中的lambda函数
  • Ajax入门
  • MapReduce基础原理、MR与MPP区别
  • 位运算符让人反胃
  • selenium环境搭建
  • Python-OpenCV中的图像处理-霍夫变换
  • 最强自动化测试框架Playwright(10)- 截图
  • SQL常见命令语句