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 EXPORT
    DIM I AS Short
    DIM TString AS STRING
                
    I = 0 : TString = ""
            
    ' code goes here
    FOR I = 2 TO 1 STEP -1
        TString=TString+RIGHT(("0"+LTRIM(HEX(ASC(MID(MKShort(Param1),I,1))))),2)
     NEXT I
     
    FUNCTION = 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 EXPORT
    DIM I AS INTEGER
    DIM TString AS STRING

    I=0: TString=""

    ' code goes here
    FOR I = 4 TO 1 STEP -1
        TString=TString+RIGHT(("0"+LTRIM(HEX(ASC(MID(MKS(1.0*Param1),I,1))))),2)
    NEXT I
    FUNCTION = StringtoBStr(TString)
END FUNCTION

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

FUNCTION myINSTRU (BYVAL Param1 AS BStr) As BSTR EXPORT
    DIM LParam1 AS STRING
    DIM RETURNSTR AS STRING

    RETURNSTR = "UNKNOWN"

    LParam1 = BStrToString(Param1)
    SELECT CASE LParam1
        CASE "VERSION"
             RETURNSTR = "VERSION 1.00 9AUG2023"
        CASE "AUTHOR"
             RETURNSTR = "Mongnewer"
    END SELECT
    FUNCTION = 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,L
    Function = 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直连互通。这些东西都挺古老了,就不赘述了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/70752.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iOS开发-实现二维码扫一扫Scan及识别图片中二维码功能

iOS开发-实现二维码扫一扫Scan及识别图片中二维码功能 在iOS开发中,会遇到扫一扫功能,扫一扫是使用摄像头扫码二维码或者条形码,获取对应二维码或条形码内容字符串。通过获得的字符串进行跳转或者打开某个页面开启下一步的业务逻辑。 https…

布局性能优化:安卓开发者不可错过的性能优化技巧

作者:麦客奥德彪 当我们开发Android应用时,布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验,使应用更加流畅、响应更加迅速,而低效的布局则会导致应用的运行变得缓慢,甚至出现卡顿、崩溃等问题&…

npm ERR! code ERESOLVEnpm ERR! ERESOLVE unable to resolve dependency tree

拉取项目到本地 执行 npm install 报错 遇到这个问题首先确认的就是版本是不是太高了,降一下版本。或者通过yarn命令替代npm install命令安装,同理,启动也可以采用yarn dev 启动代替npm run dev 下面教大家用一个NVM工具,这个工…

SSL握手协议相关概念

下图为握手协议的流程图,具体的解释参考博客: 【下】安全HTTPS-全面详解对称加密,非对称加密,数字签名,数字证书和HTTPS_tenfyguo的博客-CSDN博客 下面梳理一下SSL协议中的一些细节。首先是相关名词:证书、…

深度学习基础知识笔记

深度学习要解决的问题 1 深度学习要解决的问题2 应用领域3 计算机视觉任务4 视觉任务中遇到的问题5 得分函数6 损失函数7 前向传播整体流程8 返向传播计算方法1 梯度下降 9 神经网络整体架构11 神经元个数对结果的影响12 正则化和激活函数1 正则化2 激活函数 13 神经网络过拟合…

前端开发常见效果

目录 css实现图像填充文字 css实现手风琴效果 css实现网站变灰色 elementUi的导航栏效果 css实现滚动吸附效果 鼠标经过&#xff0c;元素内部放大 css实现图像填充文字 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta c…

5.2 互联网通信安全

数据参考&#xff1a;CISP官方 目录 一、什么是互联网通信安全二、为什么要关注互联网通信安全三、电子邮件应用安全四、即时通讯应用安全 一、什么是互联网通信安全 1、互联网通信应用的概念 通信的进化史 互联网通信技术&#xff08;OSI七层模型&#xff09; 互联网应…

Effective Java笔记(29)优先考虑泛型

一般来说 &#xff0c;将集合声 明参数化&#xff0c;以及使用 JDK 所提供的泛型方法&#xff0c;这些都不太困难 。编写自己的泛型会比较困难一些&#xff0c;但是值得花些时间去学习如何编写 。 以简单的&#xff08;玩具&#xff09;堆校实现为例 &#xff1a; // Object -…

创新引领城市进化:人工智能和大数据塑造智慧城市新面貌

人工智能和大数据等前沿技术正以惊人的速度融入智慧城市的方方面面&#xff0c;为城市的发展注入了强大的智慧和活力。这些技术的应用不仅令城市管理更高效、居民生活更便捷&#xff0c;还为可持续发展和创新奠定了坚实的基础。 在智慧城市中&#xff0c;人工智能技术正成为城市…

分享一组天气组件

先看效果&#xff1a; CSS部分代码&#xff08;查看更多&#xff09;&#xff1a; <style>:root {--bg-color: #E9F5FA;--day-text-color: #4DB0D3;/* 多云 */--cloudy-background: #4DB0D3;--cloudy-temperature: #E6DF95;--cloudy-content: #D3EBF4;/* 晴 */--sunny-b…

TypeScript 中【class类】与 【 接口 Interfaces】的联合搭配使用解读

导读&#xff1a; 前面章节&#xff0c;我们讲到过 接口&#xff08;Interface&#xff09;可以用于对「对象的形状&#xff08;Shape&#xff09;」进行描述。 本章节主要介绍接口的另一个用途&#xff0c;对类的一部分行为进行抽象。 类配合实现接口 实现&#xff08;impleme…

中科亿海微RAM使用

引言 FPGA&#xff08;Field Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;是一种可编程逻辑设备&#xff0c;能够根据特定应用的需求进行配置和重新编程。在FPGA中&#xff0c;RAM&#xff08;Random Access Memory&#xff0c;随机存取存储器&#xff09…

Maven在IDEA2021版本中全局配置(一次配置处处生效)

前言 我们在开发中&#xff0c;Maven是必不可少的&#xff0c;但是每次都需要设置一遍Maven的仓库和settings.xml。真的是心累&#xff0c;今天教大家全局配置一下。再也不要每次项目都配了&#xff0c;Maven还经常出问题。 解决方案 友情提示&#xff1a;小编的IDEA版本为2…

【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)

你可以使用 Jersey 和 CXF 这些来写一个 Rest 或 SOAP 服务的java客服端。 你也可以直接使用 Apache HttpClient 来实现。但是 Feign 的目的是尽量的减少资源和代码来实现和 HTTP API 的连接。 *通过自定义的编码解码器以及错误处理&#xff0c;你可以编写任何基于文本的 HTT…

改进DevSecOps框架的 5 大关键技术

Markets and Markets的一项研究显示&#xff0c;全球DevOps的市场规模从2017年的29亿美元增加到2023年的103.1亿美元&#xff0c;预测期的年复合增长率(CAGR)为24.7%。人们对DevOps越来越感兴趣&#xff0c;因为DevOps不仅能够压缩软件的交付周期&#xff0c;还能提高交付的速度…

c++QT文件操作

1 介绍 QT的文件操作来源于其抽象基类QIODevice&#xff0c;中用于处理输入输出设备。提供了统一的接口来处理不同类型的数据源&#xff0c;如文件、套接字、缓冲区等。QIODevice 主要用于读取和写入数据&#xff0c;无论数据来自何种源头&#xff0c;都可以通过 QIODevice 统一…

HDFS中snapshot快照机制

HDFS中snapshot快照机制 介绍作用功能实现相关命令和操作相关命令 介绍 snapshot是数据存储的某一时刻的状态记录&#xff0c;备份&#xff08;backup&#xff09;则是数据存储的某一个时刻的副本HDFS snapshot快照是整个文件系统或某个目录在某个时刻的镜像&#xff0c;该镜像…

安路FPGA的赋值报错——移位处理,加括号

authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 在使用移位符号用来当作除以号使用时&#xff0c;发现如下问题 其中 cnt_8K 为偶数和奇数时输出的数据不一样 reg [10:0] cnt_8K; reg [10:0] ram1_addra; always(posedge clk_16M) begin if(ram_out_flag )begin if(…

20230811导出Redmi Note12Pro 5G手机的录音机APP的录音

20230811导出Redmi Note12Pro 5G手机的录音机APP的录音 2023/8/11 10:54 redmi note12 pro 录音文件 位置 貌似必须导出录音&#xff0c;录音的源文件不知道存储到哪里了&#xff01; 参考资料&#xff1a; https://jingyan.baidu.com/article/b87fe19e9aa79b1319356842.html 红…

【MySQL】InnoDB存储引擎详解

InnoDB引擎是MySQL5.5版本之后默认的存储引擎 逻辑存储结构 首先是表空间Tablespace&#xff08;ibd文件&#xff09;&#xff1a;一个mysql实力可以对应多个表空间&#xff0c;用于存储及记录&#xff0c;索引等数据 这些存储记录&#xff0c;索引等数据中是用段(Segment)来…