文档章节

VB6 调用 Nim 生成的 DLL

彩色的铅笔盒
 彩色的铅笔盒
发布于 2016/10/26 14:56
字数 1062
阅读 106
收藏 1

关于 Nim

Nim 是德国人 开发的编程语言,最初叫 Nimrod。Nim 有下面几个特点:

  • 强制缩进语法
  • AST 操控
  • 编译到 C
  • 静态编译 .exe 或 dll
  • 指针
  • gc

Nim 的标准库还可以,一些常用的算法、网络库都有,也有不少的 wrapper 库。

生成 DLL

Nim 可以很方便地生成 Dll 文件,只需要在导出的 proc 中加入编译指令 {.stdcall, exportc, dynlib.};编译时使用参数:nim c --app:dll -d:release src.nim

例如

proc return_multiply*(a, b: int): int {.stdcall, exportc, dynlib.} =
    a * b

有一点需要注意的是,(似乎)因为编译器的问题,DLL 导出的函数名可能会编写的时候不一致,可以用 Dependency Walker 之类的工具查看。

比如上面的例子,导出的函数 return_multiply ,以 stdcall 调用方式编译后,入口为 return_multiply@8

VB6 代码,只需要声明就可以使用 DLL 中的函数。

Public Declare Function return_multiply Lib "test.dll" Alias "return_multiply@8" (ByVal a As Long, ByVal b As Long) As Long

对于简单的数据类型,VB6 与外部 DLL 交互还是比较简单的,问题是实际编程中更常见的复合数据类型,像字符串之类的应该如何处理。

VB6 字符串

VB6 是一个 IDE 也是一个语言。话说 MS 早期便是造 Basic 工具起家的,传说 Bill Gate 也参与编写当年 Basic 解释器的代码。VB 的发展几乎是 COM 组件的发展吏了,VB 也可以也认为是一个 MS 官方提供的 COM 组件快速使用工具。VB 的底层设计主要就是为了 COM 组件设计的。

COM 组件又复杂无庞大,是 Windows 的基础技术之一,就算 Windows 10 估计也留有不少古老代码。

VB 字符串类型实际上一种名为 BSTR 的 COM 字符串。因为 COM 组件被设计为可用于不同语言之间交互,所以在字符串设计上,是采用独立的做法。

BSTR 可以包含 NULL 字符串;由被调用者申请内存,调用者释放内存,并提供统一的内存申请释放方法;一个 BSTR 字符串由两部组成,第一部分表示字符串字节长度,第二部分是字符数组,字符数组不以 NULL 为终结标志。

一个 VB 字符串,实际是一个指向一个 BSTR 字符数组的第一个字符的指针。所有在与 C 代码交互时,一个 VB 字符串相当于一个 char* 指针,可以直接用于需要 cstring 的地方。

对于字符串必须要考虑编码问题。VB6 内部是 Unicode 编码的,但对外全部都是 ASCII。当年在开发 VB6 的时候,Windows API 只有 A 版本,字符串不编码之间的转换由编译器自动完成。可以这样认为,VB6 还不是一个完全体,可惜已经没有 VB7 了。

另一个与 VB 字符串相关的就是 LPSTR 类型,相当一部分的 Windows API 包含有 LPSTR 类型的参数。MS 官方是这样定义 LPSTR

The LPSTR type and its alias PSTR specify a pointer to an array of 8-bit characters, which MAY be terminated by a null character.

typedef char* PSTR, *LPSTR;

LPSTR 是 PSTR 的一个别名,是一个 8 位字符数组的指针,这个数组可能不是以 NULL 字符结尾的。大部分情况下 BSTRLPTSTR 是指的同样的数据结构,可以互换。

Nim 示例

根据 VB 的这些特点,写一个简单的字符串处理函数。

import encodings

const
    vbCodePage = "GB2312"
    vbTrue* = 1
    vbFalse* = 0

type
    VBString* = cstring
    VBBoolean* = int32
    
proc fromVBString*(a: VBString): string =
    return encodings.convert($a, "UTF-8", vbCodePage)
    
proc `$` (a: VBString): string =
    return fromVBString(a)

proc toVBString*(a: string): VBString =
    return VBString(encodings.convert(a, vbCodePage, "UTF-8"))

Nim 的字符串是 UTF-8 编码的,VB 的字符串是按系统 CodePage 编码的(中文环境下为 GB2312),需要一些编码转换操作,使用 Nim 标准库 encodings 实现。

下面实现一个 MD5 计算函数让 VB 调用。

import md5

proc build*(str: string): string =
    result = md5.getMD5(str)
# 计算 MD5
#
proc md5sum*(str: VBString): VBString {.stdcall, exportc, dynlib.} =
    return md5sum.build($str)

© 著作权归作者所有

上一篇: base64 编码解码
下一篇: base64 编码解码
彩色的铅笔盒
粉丝 0
博文 2
码字总数 1147
作品 0
东莞
私信 提问
实现用VB.Net/(C#)开发K/3 BOS 插件的真正可行方法

转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶...

mengyinxue
2018/05/27
0
0
VB6 程序连Ora-06413解决手札

原由: Win7 x64平台,Vb6程序启动,直接启用不了; Vb6比较古老了,应当是石器时代的产物;这错误一看应当与oracle环境变量有关,而朋友确认装了oracle 9i client 32位。 经过: 由于程序写...

snowhill
2016/12/13
0
0
Nim编译和使用DLL

nimcall其实就是fastcall. 如果想使用nim来写dll可以参考:nim-invocation-example-from-c 代码转自 Nim官方论坛

路中鸟
2015/11/23
374
0
Nim各种pragma使用方法

Pragmas(编译指示) 编译指示"{."为开始, ".}"为结束, ","号为分隔符, 例如{.cdecl, importc.} deprecated pragma (弃用(分解?)指示) deprecated指示用来标记为弃用. 也可以在声明时使用, 需要......

路中鸟
2015/07/24
512
0
杀死进程,解决运行异常---让64位程序调用32位程序更流畅

上一篇随笔中写过64位程序与32位程序(https://www.cnblogs.com/Heavystudio/p/11059033.html),最近开始正式在项目中大量实现了,但又出现了一个问题, 由于32位程序中还调用了大量dll,导致...

Heavyer
06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ubuntu 19.4 安装virtual

ubuntu 安装virtual 后报错 Solve “Result Code: NS_ERROR_FAILURE (0x80004005)” VirtualBox Error In Arch Linux $ sudo /sbin/vboxconfig 报错 “debconf: DbDriver ”config“: confi......

internetafei
3分钟前
1
0
思维导图技术分享

- by 文恒

程序员的自我成长
6分钟前
1
0
《将博客搬至CSDN》

将blog,也同步到CSDN中

温安适
14分钟前
2
0
watchbog再升级,企业黄金修补期不断缩小,或面临蠕虫和恶意攻击

概要 近日,阿里云安全团队发现wacthbo挖矿团伙[1]新增了CVE_2019_5475 的漏洞利用代码,并开始进行尝试性攻击。 通过对CVE_2019_5475漏洞的生命周期进行分析后发现,漏洞批量化利用的速度正...

大涛学长
17分钟前
2
0
深入理解JVM,虚拟机类加载机制

本人免费整理了Java高级资料,一共30G,需要自己领取; 传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 类加载过程概览 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的...

李红欧巴
19分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部