VC++操作SQLserver动态库【含源码】,及动态库使用教程。

2023-11-01

VC++操作SQLserver动态库【含源码】

动态库使用Demo程序演示

#include <iostream>
#include <windows.h>
#include "sqlDataBase.h"
int main()
{
	if (SQLInit() == S_OK)
	{
		std::cout << "数据库连接成功" << std::endl;
	}
	return false;
}

使用SQLInit()函数连接数据库

【SqlDataBase】库头文件(.h)

/*

* "Copyright (c) 2021 by Sinux,Inc,liumeng"

*/

#ifndef __SQLDATABASE_H__
#define __SQLDATABASE_H__

#ifdef SQLDATABASE_EXPORTS
#define SQLDATABASEOPT_API __declspec(dllexport)
#else
#define SQLDATABASEOPT_API __declspec(dllimport)
#pragma comment(lib,"SqlDataBase.lib")
#endif

#include <string>

/**
*   SQL connect stringt
*	Provider=SQLOLEDB;Data Source=127.0.0.1,1433;Initial Catalog=sa;User Id=sa;Password=1
*	MS Access connect string
*	Provider=Microsoft.Jet.OLEDB.4.0;Data Source=../../../data/db/Demo.mdb
*/
int     SQLDATABASEOPT_API   SQLInit(
    const std::string& strDataSource = "Provider=SQLOLEDB;Data Source=127.0.0.1;Initial Catalog=sa;User Id=sa;Password=123456",
    const std::string& strName = "",
    const std::string& strPwd = ""
);

void    SQLDATABASEOPT_API   SQLDestroy();
/*
*   查询数据
*   strSQL : SQL 语句
*   strResult:  结果 xml形式
*   返回值 > 0执行成功,返回记录的条数,否则失败
*/
int     SQLDATABASEOPT_API   SQLQuery(const std::string& strSQL, std::string& strResult);

/*
*   删除数据
*/
bool    SQLDATABASEOPT_API   SQLDelete(const std::string& value);
/*
*   添加数据,需要输入id
*/
bool    SQLDATABASEOPT_API   SQLInsert(const const std::string& str);
/*
*   更新数据
*/
bool    SQLDATABASEOPT_API   SQLUpdate(const std::string& str);

#endif

【SqlDataBase】库源代码(.cpp)

#define WIN32_LEAN_AND_MEAN 
#include <windows.h>
#include <mmsystem.h>
#include <atlbase.h>

#import "C:/Program Files/Common Files/System/ado/msado15.dll"  rename("EOF","EndOfFile")

#include "SqlDataBase.h"
#include <string>
#include <sstream>

using   std::string;
using   namespace ADODB;

/************************************************************************/
/*                         互斥体对象声明                               */
/************************************************************************/
class	Mutex
{
public:
	Mutex()
	{
		/**
		*   初始化临界区对象
		*	返回值>无
		*/
		::InitializeCriticalSection(&m_cs);
	}
	~Mutex()
	{
		/**
		*   释放临界区对象
		*   返回值>无
		*/
		::DeleteCriticalSection(&m_cs);
	}
	void	Lock()
	{
		/**
		*   进入临界截面
		*   返回值>无
		*/
		::EnterCriticalSection(&m_cs);
	}
	void	UnLock()
	{
		/**
		*   离开临界截面
		*   返回值>无
		*/
		::LeaveCriticalSection(&m_cs);
	}
protected:
	CRITICAL_SECTION	m_cs;

};

/************************************************************************/
/*                         互斥锁对象声明                               */
/************************************************************************/
class	Lock
{
public:
	Lock(Mutex* pM) :m_Mutex(*pM)
	{
		m_Mutex.Lock();
	}
	Lock(Mutex& m) :m_Mutex(m)
	{
		m_Mutex.Lock();
	}
	~Lock()
	{
		m_Mutex.UnLock();
	}
public:
	Mutex& m_Mutex;
};


_ConnectionPtr	g_pConnection = NULL;
Mutex           g_Mutex;


/************************************************************************/
/*                        初始化数据库连接                              */
/************************************************************************/

int SQLDATABASEOPT_API SQLInit(
    const std::string& strDataSource,
    const std::string& strUserName,
    const std::string& strPwd
)
{
	//创建自动互斥锁将该函数加锁,保证全局对象的安全性
	Lock    lk(g_Mutex);
    //以单线程方式创建COM对象
	//Microsoft 组件对象模型 (COM) 是一个独立于平台的分布式面向对象的系统,用于创建可交互的二进制软件组件。 
	//COM 是 Microsoft 的 OLE (复合文档) 、ActiveX (Internet 组件) 等的基础技术。
    if (::CoInitialize(NULL)!= S_OK)
    {
        OutputDebugString(_T("CoInitialize  failed!\n"));
    }

	//创建ADO接口
	//ADO是微软提供的COM,用于访问数据库。
    g_pConnection.CreateInstance(__uuidof(Connection));
    try
    {
        HRESULT hr = g_pConnection->Open((_bstr_t)strDataSource.c_str(), strUserName.c_str(), strPwd.c_str(), adModeUnknown);

        return  S_OK;
    }
    catch (_com_error e)
    {
        OutputDebugString(e.Description());
        OutputDebugString(_T("\n"));
        return  e.Error();
    }
    catch (...)
    {
        return	-1;
    }

    return false;
}

/************************************************************************/
/*                              释放连接                                */
/************************************************************************/
void SQLDATABASEOPT_API SQLDestroy()
{
    g_pConnection = NULL;
}

/************************************************************************/
/*                              查询数据                                */
/************************************************************************/
int	SQLDATABASEOPT_API	SQLQuery(const string& strSQL, string& strRet)
{
    Lock    lk(g_Mutex);
    /**
    *   清空数据
    */
    strRet = "";
    _RecordsetPtr pRecordSet;
    pRecordSet.CreateInstance(__uuidof(Recordset));
    try
    {
        //打开数据库
        pRecordSet->Open
        (
            strSQL.c_str(),
            g_pConnection.GetInterfacePtr(),
            adOpenDynamic,
            adLockOptimistic,
            adCmdText
        );

        if (!pRecordSet->BOF)
        {
            pRecordSet->MoveFirst();
            OutputDebugString(_T("数据库打开数据集合成功\n"));
        }
        else
        {
            OutputDebugString(_T("暂无数据\n"));
            return 0;
        }

        std::stringstream   ss;
        ss << "<root>\n";

        int     iRecordCnt = 0;
        while (!pRecordSet->EndOfFile)
        {
            ss << "\t<record ";
            ++iRecordCnt;
            //取得表中字段数目
            long    lCnt = pRecordSet->Fields->Count;
            for (int i = 0; i < lCnt; ++i)
            {
                std::string strResult;
                //第几个字段
                FieldPtr    fields = pRecordSet->Fields->Item[long(i)];
                //字段名称
                string      fieldName = (LPCSTR)fields->GetName();
                //字段值
                _variant_t  var = pRecordSet->GetCollect(fieldName.c_str());
                if (var.vt != VT_NULL)
                {
                    strResult = (LPCSTR)_bstr_t(var);
                    std::string::iterator itr = strResult.begin();
                    for (
                        ; itr != strResult.end();
                        )
                    {
                        std::string     strData;;
                        if (*itr == '\"')
                        {
                            size_t  nPos = itr - strResult.begin();
                            strData = "&quot;";
                            strResult.replace(itr, itr + 1, strData.c_str(), strData.size());
                            itr = strResult.begin() + (nPos)+strData.size();
                        }
                        else if (*itr == '\'')
                        {
                            size_t  nPos = itr - strResult.begin();
                            strData = "&apos;";
                            strResult.replace(itr, itr + 1, strData.c_str(), strData.size());
                            itr = strResult.begin() + (nPos)+strData.size();
                        }
                        else if (*itr == '>')
                        {
                            size_t  nPos = itr - strResult.begin();
                            strData = "&gt;";
                            strResult.replace(itr, itr + 1, strData.c_str(), strData.size());

                            itr = strResult.begin() + (nPos)+strData.size();
                        }
                        else if (*itr == '<')
                        {
                            size_t  nPos = itr - strResult.begin();
                            strData = "&lt;";
                            strResult.replace(itr, itr + 1, strData.c_str(), strData.size());
                            itr = strResult.begin() + (nPos)+strData.size();
                        }
                        else if (*itr == '&')
                        {
                            size_t  nPos = itr - strResult.begin();
                            strData = "&amp;";
                            strResult.replace(itr, itr + 1, strData.c_str(), strData.size());
                            itr = strResult.begin() + (nPos)+strData.size();
                        }
                        else
                        {
                            ++itr;
                        }
                    }

                }
                ss << fieldName << " = \"" << strResult << "\" ";
            }
            ss << "/>\n";
            pRecordSet->MoveNext();
        }
        ss << "</root>";
        strRet = ss.str();
        pRecordSet->Close();
        return  iRecordCnt;
    }
    catch (_com_error e)
    {
        strRet = "";
        OutputDebugString(e.ErrorMessage());
        OutputDebugString(_T("\n"));
        return  e.Error();
    }
    catch (...)
    {
        return	-1;
    }
}

/************************************************************************/
/*                              删除数据                                */
/************************************************************************/
bool SQLDATABASEOPT_API SQLDelete(const std::string& value)
{
    try
    {
        Lock    lk(g_Mutex);
        //_CommandPtr是一种函数,功能是提交的sql查询字符串指针。
        _CommandPtr pCommand = NULL;
        //初始化Com对象
        pCommand.CreateInstance(__uuidof(Command));
        //连接数据库
        pCommand->ActiveConnection = g_pConnection;
        //命令文本
        pCommand->CommandText = value.c_str();
        //执行
        pCommand->Execute(NULL, NULL, adCmdText);
        return true;
    }
    catch (_com_error e)
    {
        OutputDebugString(e.ErrorMessage());
        return false;
    }
}

/************************************************************************/
/*                 添加数据,添加的时候需要手动输入id值                  */
/************************************************************************/
bool SQLDATABASEOPT_API SQLInsert(const std::string& str)
{
    try
    {
        Lock    lk(g_Mutex);
        _CommandPtr pCommand = NULL;
        //初始化Com对象
        pCommand.CreateInstance(__uuidof(Command));
        //连接数据库
        pCommand->ActiveConnection = g_pConnection;
        //命令文本
        pCommand->CommandText = str.c_str();
        //执行
        pCommand->Execute(NULL, NULL, adCmdText);
        return true;
    }
    catch (_com_error e)
    {
        OutputDebugString(e.ErrorMessage());
        return false;
    }
}

/************************************************************************/
/*                          更新数据库                                  */
/************************************************************************/
bool SQLDATABASEOPT_API SQLUpdate(const std::string& str)
{
    try
    {
        Lock    lk(g_Mutex);
        _CommandPtr pCommand = NULL;
        //初始化Com对象
        pCommand.CreateInstance(__uuidof(Command));
        //连接数据库
        pCommand->ActiveConnection = g_pConnection;
        //命令文本
        pCommand->CommandText = str.c_str();
        //执行
        pCommand->Execute(NULL, NULL, adCmdText);
        return true;
    }
    catch (_com_error e)
    {
        OutputDebugString(e.ErrorMessage());
        return false;
    }
}

动态库使用方法

打开 Visual Studio 这里用2019来演示,选择创建新项目
在这里插入图片描述
连着选择动态链接库DLL,各个版本的VS叫法可能不一样,总之是DLL就对了
在这里插入图片描述
项目名称取名为SqlDataBase,如果不是这个名字的话后面需要在源代码中修改,总之在动态库CPP中要写清楚.lib的名称,这个名称通常和项目名称相同。当然你也可以在项目属性中修改生成库的名称。
在这里插入图片描述

#pragma comment(lib,"SqlDataBase.lib")

创建好项目之后在解决方案视图当中Visual Studio会为我们自动创建两个.h和.cpp这里还是以Visual Studio 2019为例。当然我们不需要这些文件,所以我在这里将它删除掉
在这里插入图片描述
将它们全部删除掉,得到一个干净的工程。
在这里插入图片描述
这个时候我们创建我们的.cpp和.h,怎么创建都行了,文件名叫什么也不重要,但是为了遵循C++的代码规范,我这里还是将文件名称创建为SqlDataBase.h,SqlDataBase.cpp
在这里插入图片描述
接下来直接将我们的代码对应.h以及.cpp复制进去,然后在解决方案资源管理视图中右键我们的项目或则解决方案,都行。这个时候如果不出意外的话应该就要出意外了。
在这里插入图片描述

错误提示我们是否忘记了向源中添加#include “pch.h”
这是我们使用了预编译头的但是却把源文件删除了导致的,我们只需要在工程属性中将预编译头去掉,不使用它即可。
在这里插入图片描述
然后再进行编译这个时候如果不出意外的话也会出意外
在这里插入图片描述
我们定义的库导出函数是不运行进行导入定义的,这是我们在定义/使用 库函数的规范,如果想要详细了解的话可以参考windows动态库的有关知识。总之,我们需要对工程进行预处理器定义,告诉编译器,我们的定义的函数用于导出,也就是

#ifdef SQLDATABASE_EXPORTS
#define SQLDATABASEOPT_API __declspec(dllexport)

同样选择我们的项目右键,然后点击属性,找到C++栏,预处理器,然后将预处理定义加上SQLDATABASE_EXPORTS,我们在代码中定义的#define
在这里插入图片描述
添加进去点击确认
在这里插入图片描述
再次对工程进行生成,这个时候如果不出意外的话就不会出现意外了。
在这里插入图片描述
这个时候我们可以在Visual Studio下方输出视图中查看我们的库生成在了那里,并且找到他。做完了这些步骤之后,我们就得到了一个对SQLServer数据库操作的动态库了。我们可以进行连接,查询,删除,修改等操作。
这个时候让我们新建一个空项目来测试动态库是否可用,哦,在这之前,你需要知道,如果要使用一个动态库,需要.dll,.lib以及关于他导出函数声明的头文件。当然,如果我们生成成功了,.dll,.lib都会在生成目录中找到,头文件就直接使用SqlDataBase.h就想,因为在SqlDataBase.h中,我们也定义了有关于导入的操作
在这里插入图片描述

#define SQLDATABASEOPT_API __declspec(dllimport)
#pragma comment(lib,"SqlDataBase.lib")

好了,我们现在新创建一个名为sqlDemo的项目并把SqlDataBase.h,SqlDataBase.lib,以及SqlDataBase.dll包含在我们的项目中
我这里在工程根目录下面创建了一个名为include的文件夹,并将SqlDataBase.h放到了其中,在sqlDemo工程中,我们添加附加包含目录,就可以使用我们的SqlDataBase.h头文件了。
在这里插入图片描述
在这里插入图片描述
同样我们也设置一下lib的路径。我也是在工程根目录下面创建了一个名为lib的文件夹,然后将我们生成出来的.lib文件放到了其中
在这里插入图片描述
在这里插入图片描述
还剩下最后一步,也是最关键的一步,我们需要在sqlDemo工程属性中告诉编译器,我们需要依赖一个名为SqlDataBase的库,这样呢,编译器就会在程序编译期间将我们准备好的SqlDataBase库与我们的Demo程序连接在一起了。确保我们在首次调用库函数的时候已经加载好了库。
在这里插入图片描述
因为我们在连接器常规属性中,附加库目录中配置了我们的lib目录,所以呢,编译器也会找到我们的lib文件,如果你没有配置该目录的话,编译器就不会找到,当然如果你愿意的话,也可以直接放在程序根目录下面,且不用配置附加库目录,只不过这样看起来有一点乱,在大型工程中,对于文件的管理要求都必须清晰明了,如果我们有非常多个.lib文件的话,把他们统一放在一起是一个不错的选择。
好了,接下来就是最后一步了,将我们的DLL文件放在工程的根目录下面。
在这里插入图片描述
这个时候再运行我们的Demo程序,看看我们的动态库是否能正常运行起来
在这里插入图片描述

关于数据库的连接您可以访问SQLInit()的构造函数,如果您不清楚数据库的搭建,嗯,我想您可以查阅一些书籍,或则是上网求助,如果可以,您也可以询问一下身边经验丰富的同事。总之这里不涉及数据库搭建的操作。
PS:严格来讲,您不需对sqlDemo程序进行附加依赖库的操作,因为如果您的sqlDemo程序已经成功包含了sqlDataBase.h头文件,在程序编译的过程中呢就会连接lib库了

#define SQLDATABASEOPT_API __declspec(dllimport)
#pragma comment(lib,"SqlDataBase.lib")

我们在头文件中说明了库的导入。
所以,在进入main函数之前,或则说在编译Demo.cpp中就已经导入了动态库,您无需担心在使用库函数之前是否已经加载进了库。但在这所有所有之前,您至少需要让编译器找到您的lib库。
祝您好运~~~~

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

VC++操作SQLserver动态库【含源码】,及动态库使用教程。 的相关文章

  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 在 Sql Server 中转换为日期时间 MM/dd/yyyy HH:mm:ss

    如何将给定的日期格式转换为MM dd yyyy HH mm ss 我尝试了下面这个但没有实现 谁能帮我 SELECT CONVERT VARCHAR 20 GETDATE 120 SQL Server 2005及以上版本支持 SELECT
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲

随机推荐

  • <QT>预览界面与实际输出界面不一样

    这是由于QT对于高分辨率的屏幕存在像素上的偏差 在main函数第一行加上以下代码 if QT VERSION gt QT VERSION CHECK 5 6 0 QCoreApplication setAttribute Qt AA Ena
  • 打包3阶段-使用Enigma Virtual Box打包为独立exe程序

    一 首先了解一下Enigma Virtual Box 百科 Enigma Virtual Box是软件虚拟化工具 它可以将多个文件封装到应用程序主文件 从而制作成为单执行文件的绿色软件 它支持所有类型的文件格式 虚拟化后的软件不释放任何临时
  • C语言程序设计超详细复习总结

    C语言 注意 要了解c语言的函数库 会使用里面的函数 如math h stdlib h库 rand 函数等 计算机元素 1 机器语言 机器指令的集合 机器指令 计算机能够识别的二进制代码 2 符号语言 汇编语言 一些英文字母和数字表示一个指
  • 制作双击可以直接运行的jar包

    原文地址 http www cnblogs com ylawrence3 archive 2009 11 08 1350645 html 1 JAR 文件包 JAR 文件就是 Java Archive File 顾名思意 它的应用是与 Ja
  • Android中启动一个服务,Android服务的两种启动方式

    前言 Service是Android的四大组件之一 也是可执行的程序 服务是Android中实现程序后台运行的解决方案 非常适合去执行那些不需要和用户交互而且还要求长期运行的任务 Service的启动方式有两种 总结一下两种方式的区别 一
  • Leetcode 14 string::find / substr

    思想 利用C string find 函数的特性 暴力匹配 重要特性 substr start length 如果 length 为 0 或负数 将返回一个空字符串 string find str 匹配返回首下标 不匹配返回string n
  • Idea Sonar使用说明

    1 Sonarlint安装 1 1 Idea在线安装 1 打开idea file 文件 setting 设置 1 插件搜索sonarlint进行安装 1 2 Idea离线安装 若idea 无法下载安装该插件 在idea https plug
  • opencv(十三)--边缘检测和梯度

    目标 图像梯度 图像边界等 使用到的函数有 cv2 Sobel cv2 Schar cv2 Laplacian 等 原理 梯度简单来说就是求导 OpenCV 提供了三种不同的梯度滤波器 或者说高通滤波器 Sobel Scharr 和Lapl
  • Qt 之 QVideoFrame转换为QImage

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 方法一 最简单 方法二 依赖opencv 方法三 qt5 15版本 前言 在qt框架下 实现相机预览的几种方式在qt相机预览已经描述过了 在该文章的几种方式中
  • 二叉搜索树(数组实现)

    内容 建立二叉搜索树 bool buildtree int k tree k value a index int cur 0 if index a size return true while 1 if a index lt tree cu
  • 正整数序列的数

    正整数序列的数 正整数序列的数量 问题描述 小明想知道 满足以下条件的正整数序列的数量 1 第一项为 n 2 第二项不超过 n 3 从第三项开始 每一项小于前两项的差的绝对值 请计算 对于给定的 n 有多少种满足条件的序列 输入格式 输入一
  • Qt使用gSoap实现webservice服务端和客户端

    文章目录 gSoap工具介绍 1 下载 2 Hello world 开始使用SOAP api 2 1 新建文件夹 2 2 新建服务接口头文件 hello h 2 3 使用 soapcpp2 exe 2 4 拷贝源代码库文件 2 5 Qt 服
  • 第二次作业:微信案例分析

    2 1 介绍产品相关信息 你选择的产品是 微信 为什么选择该产品作为分析 微信是一款全方位的手机通讯应用 帮助我们轻松连接全球好友 微信可以通过SMS MMS网络发送短信 进行视频聊天 与好友一起玩游戏 以及分享自己的生活到朋友圈 让我们感
  • Stable Diffusion 个人推荐的各种模型及设置参数、扩展应用等合集(不断更新中)

    本文主要是把平时使用的模型及其参数进行推荐和整理 相关 安装及其问题解决参考 Windows安装Stable Diffusion WebUI及问题解决记录 运行使用时问题 Windows使用Stable Diffusion时遇到的各种问题整
  • Stack,ArrayDeque,LinkedList的区别

    这段时间把疯狂JAVA再看了一遍 发现Stack ArrayDeque LinkedList都可以作为栈使用 所以就稍微从性能以及实现的细节对比这三者的区别 类继承树 由继承树看出 三者都是Collection的间接实现类 ArrayDeq
  • js中数组删除对象的几种方式总结

    1 关键字删除 2 splice删除 3 特殊位置删除 一 关键字删除 关键字删除是通过js提供的关键字 delete手动删除数组的某一项 使用delete删除掉数组中的元素后 会把该下标出的值置为undefined 数组的长度不会变 ar
  • 一个案例说明高层属性形式化验证

    1 验证软件功能介绍 Beosin VaaS的业务逻辑验证软件 是一款用来检测智能合约上层业务逻辑漏洞的软件 基于合约的白皮书 软件利用形式化方法 首先对单个函数进行属性的描述 在对单个函数进行属性的验证并通过后 基于这些已验证属性 抽取出
  • 号传到服务器为空,URL 传+号到后台变空格问题解决方案

    今天在调试客户端向服务器传递参数时 参数中的 全部变成了空格 原因是URL中默认的将 号转义了 解决方法如下 方法一 修改客户端 将客户端带 的参数中的 全部替换为 2B 这样参数传到服务器端时就能得到 了 方法二 修改服务器端 将空格替换
  • 第六天作业

    include
  • VC++操作SQLserver动态库【含源码】,及动态库使用教程。

    VC 操作SQLserver动态库 含源码 动态库使用Demo程序演示 include