基于vspd DLL二次开发的虚拟串口工具

2023-11-12

最近项目需要,早期使用com0com做虚拟串口工具的二次开发,但是发现在系统兼容性上存在很多的问题,后来改用vspd 的免费dll做开发,在稳定性和兼容性上确实提升了很多。功能调用非常简单,可以参照如下的demo。库文件的话自行下载和链接。需要源码可以留言。
有一点需要提醒的是,使用该vspd的dll创建的虚拟串口对,在电脑重启之后将不会存在,其原因是创建的虚拟串口对没有写入到注册表中。具体操作请自行尝试。如果需要,亦可以留言。

#include <iostream>
#include <Windows.h>
#include <WinBase.h>
using namespace std;


#define USAGE_FMT  "SetUp for UVSPDTool\n" \
    "Usage:\n" \
    "<command> [options] \n" \
    "Examples:\n" \
    "install PortName=COM3 PortName=COM4\n" \
    "remove PortName\n" \
    "delete all\n" \
    "----------------------------------------"
#define PROGRAME_VERSION "1.00.0001"
#define DEFAULT_PROGNAME "UVSPDTool"
#define COMPANY          "JulySun"

/**
 ** 使用vspd提供的第三方库,提供用户创建、删除和删除全部虚拟串口对的API
 ** bool CreateVSPair(char *Port1, char *Port2);//创建虚拟串口对
 ** bool DeleteVSPair(char* Port1);删除虚拟串口对
 ** bool DeleteAllVSPair(void);//删除所有虚拟串口
 */

typedef bool (__stdcall *CreatePairFn)(char *Port1, char *Port2);
typedef bool (__stdcall *DeletePairFn)(char *Port1);
typedef bool (__stdcall *DeleteAllFn)(void);
typedef bool (__stdcall *SetStrictBaudrateName) (char *Port, bool StrictBaudrate);
typedef bool (__stdcall *SetStrictBaudrateHandle) (HANDLE hPort, bool StrictBaudrate);
typedef bool (__stdcall *SetStrictBaudrateFn)(char *Port, bool StrictBaudrate);
typedef bool (__stdcall *SetBreakFn)(char *Port, bool bBreak);
typedef bool (__stdcall *QueryBusFn)(void* InBuffer, long sizeInBuffer, void* OutBuffer, long sizeOutBuffer);
typedef bool (__stdcall *SetWiringFn)(char *Port, void *Buffer, long sizeBuffer);


bool CreateVSPair(char *Port1, char *Port2) {

    OSVERSIONINFO VersionInfo;
    HINSTANCE libInst;
    bool returnvalue = false;

    VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&VersionInfo);

    if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
        libInst = LoadLibrary(L"VSPDCTL64.DLL");
    else
        libInst = LoadLibrary(L"VSPDCTL.DLL");

    if (!libInst) return false; /* Couldn't load library */
    /* Substitute the typedefs above for functions other than CreatePairFn */
    CreatePairFn CreatePair=(CreatePairFn)GetProcAddress(libInst, "CreatePair");
    if (CreatePair==0) return false; /* Couldn't find function */
    returnvalue=CreatePair(Port1, Port2); /* For example, Port1 = "COM5" and Port2 = "COM6" */
    FreeLibrary(libInst);
    return returnvalue;
}

bool DeleteVSPair(char* Port1){
    OSVERSIONINFO VersionInfo;
    HINSTANCE libInst;
    bool returnvalue = false;

    VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&VersionInfo);

    if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
        libInst = LoadLibrary(L"VSPDCTL64.DLL");
    else
        libInst = LoadLibrary(L"VSPDCTL.DLL");

    if (!libInst) return false; /* Couldn't load library */
    /* Substitute the typedefs above for functions other than CreatePairFn */
    DeletePairFn DeletePair=(DeletePairFn)GetProcAddress(libInst, "DeletePair");
    if (DeletePair==0) return false; /* Couldn't find function */
    returnvalue=DeletePair(Port1);
    FreeLibrary(libInst);
    return returnvalue;
}

bool DeleteAllVSPair(void){
    OSVERSIONINFO VersionInfo;
    HINSTANCE libInst;
    bool returnvalue = false;

    VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&VersionInfo);

    if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
        libInst = LoadLibrary(L"VSPDCTL64.DLL");
    else
        libInst = LoadLibrary(L"VSPDCTL.DLL");

    if (!libInst) return false; /* Couldn't load library */
    /* Substitute the typedefs above for functions other than CreatePairFn */
    DeleteAllFn DeleteAll=(DeleteAllFn)GetProcAddress(libInst, "DeleteAll");
    if (DeleteAll==0) return false; /* Couldn't find function */
    returnvalue=DeleteAll();
    FreeLibrary(libInst);
    return returnvalue;
}



/**
 * @brief main
 * @param argc
 * @param argv
 * @return
 */

int main(int argc,char* argv[])
{
    if(argc > 2){
        char** pargs = argv;
        while( *pargs != NULL){
            if(!strcmp (*pargs,"--help")){ // 帮助文档
                printf ("%s\n",USAGE_FMT);
            }
            if(! strcmp(*pargs,"--version")){ // 版本信息
                printf("company: %s \t programe:%s version:%s\n",COMPANY,DEFAULT_PROGNAME,PROGRAME_VERSION);
            }
            if( !strcmp (*pargs,"install")){ // 安装串口模式
                char port1[20]={0};
                char port2[20]={0};
                sscanf(*(++pargs),"PortName=%s",port1);
                sscanf (*(++pargs),"PortName=%s",port2);
                printf("install PortName=%s PortName=%s\n",port1,port2);

                if( !(strlen(port1) && strlen (port2)) ){
                    printf("parame error...");
                    break;
                }

                bool flag = CreateVSPair (port1,port2);
                if(flag){
                    printf("create vspd:( %s,%s) successed\n",port1,port2);
                }else{
                    printf("create vspd:( %s,%s) failed\n",port1,port2);
                }
            }
            if( !strcmp( *pargs,"remove")){ // 删除串口模式 remove [COMn]
                if( ! *(++pargs)){ printf("parameter error!\n");}
                bool flag = DeleteVSPair(*pargs);
                if(flag){
                    printf("delete virtual serial port(%s) successed.\n",*pargs);
                }else{
                    printf("delete virtual serial port(%s) failed.\n",*pargs);
                }
            }
            if( !strcmp( *pargs,"delete")){ // 删除串口模式 remove [COMn]
                bool flag = DeleteAllVSPair ();
                if(flag){
                    printf("delete all virtual serial ports successed.\n");
                }else{
                    printf("delete all virtual serial ports failed.\n");
                }
            }
            pargs++;
        }
    }
    return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于vspd DLL二次开发的虚拟串口工具 的相关文章

随机推荐

  • L1-058 6翻了 (15 分)-PAT 团体程序设计天梯赛 GPLT

    解题思路 遍历字符串 不是6字符的直接输出 出现6的时候 往后判断出现了几次6 进而决定是否替换字符串 include
  • Swift5 不是循环的双链表

    小萌毕业5年了 一直在做移动端的工作 OC和Swift 最近比较流行的就是Swift了 学习过OC和Swift的基本原理 听的云里雾里的 听了好几遍才理解 因此下定决心要学习数据结构 学习之后发现数据结构和算法不愧是开发人员必学的知识 双链
  • Visual Studio 2019实现c51上位机控制数码管显示数字

    Visual Studio 2019实现c51上位机控制数码管显示数字 初学者编写上位机程序 上位机编写环境 上位机窗体设计 上位机界面功能代码 form界面 打开串口 代码 发送 按钮代码 上位机机全部代码 单片机烧录代码 效果图 初学者
  • PAT1-第39级台阶(递归)

    第39级台阶 小明刚刚看完电影 第39级台阶 离开电影院的时候 他数了数礼堂前的台阶数 恰好是39级 站在台阶前 他突然又想着一个问题 如果我每一步只能迈上1个或2个台阶 先迈左脚 然后左右交替 最后一步是迈右脚 也就是说一共要走偶数步 那
  • 捕鱼游戏、slots游戏出海技术支持

    捕鱼和slots类游戏的核心为数值 在美术 程序 音效 玩法都OK的情况下 数值是核心 这类游戏的数值思维方式要区别于其它类型的游戏看待 对于转型进入这个领域的团队和老板在数值上面 算法上面没有积累 对产品理解不够深入最后都是以失败告终 在
  • [QNX700]QNX 7.0 平台QT开发环境配置

    锋影 email 174176320 qq com 如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 声明 本文只用于个人学习交流 若不慎造成侵权 请及时联系我 立即予以改正 1 QNX q
  • feign 出现 too many bytes written executing xx Or incomplete output stream executing xx

    问题 通过FeignClient调用第三方接口时 出现如下报错 incomplete output stream executing xxx 或者 too many bytes written executing POST 解决办法 自定义
  • 【windows系统cmd下打开管理员模式】

    runas noprofile user Administrator cmd
  • 离职报告提交前一秒,再检查下这些测试思维面试题你都会了么?

    创建坐席组的功能模块 如何进行测试用例设计 解答 功能测试 使用等价类划分法去分析创建坐席的每个输入项的有效及无效类 同步考虑边界值去设计对应的测试用例 先进行冒烟测试 正常创建坐席 坐席组编号自动生成且确认 6 位数字唯一 名称输入 10
  • UE4材质11_材质参数集

    11 1 参数集全局控制材质 创建材质参数集 MPC 材质参数集的前缀 材质参数集可以添加标量和向量 标量一般就是数字 向量就是颜色或者是X Y Z 一个材质最多只能使用两个材质参数集 11 2 蓝图传递参数集及实例参数 打开关卡蓝图 添加
  • WPF中WindowFormsHost始终置顶的有效解决方案

    背景 WPF的原生控件并不具备自身的句柄 即使使用偏门的方式获取的结果也都是控件所在窗体的句柄 并不代表该控件本身的资源 这是由WPF的自身的机制决定的 csharp IntPtr hwnd1 new WindowInteropHelper
  • 【从零开始学QuartusII封装网表文件】——FPGA设计不积跬步101

    从零开始学QuartusII封装网表文件 FPGA设计不积跬步101 如果你正在从事FPGA的设计工作 你一定会遇到需要在PCB中使用FPGA芯片的情况 此时就需要进行封装网表文件 本文将为大家介绍如何使用QuartusII软件进行封装网表
  • VS:define_CRTDBG_MAP_ALLOC宏检测windows上的code是否有内存泄露

    VS中自带内存泄露检测工具 若要启用内存泄露检测 则在程序中添加以下语句 define CRTDBG MAP ALLOC include
  • matlab 极坐标画圆

    clc clear all t linspace 0 2 pi 50 a size t r 2 ones a figure 1 polar t r r linspace函数的用法 linspace x1 x2 N x1 x2 N分别为起始值
  • Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解...

    初学hibernate的童鞋 刚开应该都有这种感觉 hibernate的配置文件好麻烦 还不如jdbc访问数据库呢 直接写代码 多方便 用hibernate还要写代码 还要写配置 太麻烦了 至少我刚开始学习的时候就是这么想的 配置文件确实有
  • java代码的执行顺序

    1 java代码的执行顺序如下 开始 gt 父类的静态代码块 gt 子类的静态代码块 gt 父类的普通代码块 gt 父类的构造方法 gt 子类的普通代码块 gt 子类的构造方法 gt 结束 注意事项 1 静态代码块 也就是被关键字stati
  • HTTP系列(七)—— 网关

    在 HTTP 刚诞生的年代 人们只是使用它来发送静态的在线文档 但是随着用户需求的驱动 静态的资源已经无法满足人们的需求了 人们更加期望的是在 Web 上发布复杂的资源 所以 为了解决这个问题 就提出了网关的概念 什么是网关 网关 抽象出了
  • 编译原理 CS-143(更新至week4)

    编译原理 CS 143 Pre Course Survey Navigation Your Course 01 01 Introduction 8m20s 01 02 Structure of a Compiler 13m53s 编译器结构
  • AcWing 238. 银河英雄传说 并查集模板题

    题 参考 include
  • 基于vspd DLL二次开发的虚拟串口工具

    最近项目需要 早期使用com0com做虚拟串口工具的二次开发 但是发现在系统兼容性上存在很多的问题 后来改用vspd 的免费dll做开发 在稳定性和兼容性上确实提升了很多 功能调用非常简单 可以参照如下的demo 库文件的话自行下载和链接