静态调用dll,通过参数读写在ini文件中来完成

对于dll文件有两种读取方式

预备知识:

     1、如果在没有导入库文件(.lib),而只有头文件(.h)与动态链接库(.dll)时,我们才需要显示调用,如果这三个文件都全的话,我们就可以使用简单方便的隐式调用。

     2、通常Windows下程序显示调用dll的步骤分为三步(三个函数):LoadLibrary()、GetProcAdress()、FreeLibrary()

 其中,LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)

         GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用

         FreeLibrary() 释放dll所占空间 

 

第一:隐式调用

对于完成的dll .lib 和.h文件。调用起来非常简单。平常用到的opencv,其实在调用的时候就是隐式调用。

配置opencv的过程就是对于dll的隐式调用的过程。

1)将.h文件的路径配置在工程属性   c/c++ ->附加包含目录

2)将.lib文件放在链接器-》附加库目录、

3)将****.lib的名字放在链接器-》输入-》附加依赖项里

3)将dll放在自己的输出目录就ok了

后面在程序里包含头文件之后就正常调用函数就ok了

第二 本文重点讲的是显式调用

显示调用是没有.lib的情况下怎么调用?

以qt为例!

#include <QApplication>
  #include <QLibrary>
#include <QDebug>
#include <QMessageBox>
#include "dll.h"             //引入头文件
typedef int (*Fun)(int,int); //定义函数指针,以备调用
int main(int argc,char **argv)
{
     QApplication app(argc,argv);
     QLibrary mylib("myDLL.dll");   //声明所用到的dll文件
     int result;
     if (mylib.load())              //判断是否正确加载
     {
         QMessageBox::information(NULL,"OK","DLL load is OK!");
        Fun open=(Fun)mylib.resolve("add");    //援引 add() 函数
         if (open)                  //是否成功连接上 add() 函数
         {
             QMessageBox::information(NULL,"OK","Link to Function is OK!");
             result=open(5,6);      //这里函数指针调用dll中的 add() 函数
             qDebug()<<result;
        }
        else
             QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");
    }
    else
        QMessageBox::information(NULL,"NO","DLL is not loaded!");
        return 0;  //加载失败则退出

}

这里有一个关键的一句代码

typedef int (*Fun)(int,int); //定义函数指针,以备调用

如果该函数指针定义的和dll中的函数接口不一致的话,后续在loadlibary的时候就会失败。所以为了在使用动态链接库的时候能够具有好的移植性,这里引入ini文件,具体的操作就是:

1)将动态链接库中的函数名称格式定好,(最好包含必须的输入元素以图象为例就是只声明输入为image,输出region)

2)所有在该函数中要输入的控制参数都写到ini文件中

3)在调用的时候,就是在ini文件中读取参数来调用。

生成dll的代码:

#include "stdafx.h"
#include<string>
#ifndef __APPLE__
#  include "HalconCpp.h"
#  include "HDevThread.h"
#  if defined(__linux__) && !defined(__arm__) && !defined(NO_EXPORT_APP_MAIN)
#    include <X11/Xlib.h>
#  endif
#else
#  ifndef HC_LARGE_IMAGES
#    include <HALCONCpp/HalconCpp.h>
#    include <HALCONCpp/HDevThread.h>
#  else
#    include <HALCONCppxl/HalconCpp.h>
#    include <HALCONCppxl/HDevThread.h>
#  endif
#  include <stdio.h>
#  include <HALCON/HpThread.h>
#  include <CoreFoundation/CFRunLoop.h>
#endif
using namespace HalconCpp;

LPCWSTR stringToLPCWSTR(std::string orig);
std::string TCHAR2STRING(TCHAR* str);
extern "C" __declspec(dllexport)  void testThreshold(HObject inputImg,HObject  *outputImg)
{
	
	TCHAR buf[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, buf);
	std::string str1 = TCHAR2STRING(buf);
	str1 += "\\testdll.ini";
	float a = ::GetPrivateProfileInt(L"threshold", L"low", 0, stringToLPCWSTR(str1));
	float b = ::GetPrivateProfileInt(L"threshold", L"up", 0, stringToLPCWSTR(str1));
	Threshold(inputImg, outputImg, a, b);//阈值分割

	//int c = a + b;
	//std::string str = std::to_string(c);
	::WritePrivateProfileString()
	//::WritePrivateProfileString(L"y", L"c", stringToLPCWSTR(str), stringToLPCWSTR(str1));

	//return c;
}
LPCWSTR stringToLPCWSTR(std::string orig)
{
	size_t origsize = orig.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);

	return wcstring;
}
/******************************************************************************************
Function:        TCHAR2STRING
Description:     TCHAR转string
Input:           str:待转化的TCHAR*类型字符串
Return:          转化后的string类型字符串
*******************************************************************************************/
std::string TCHAR2STRING(TCHAR* str)
{
	std::string strstr;
	try
	{
		int iLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);

		char* chRtn = new char[iLen * sizeof(char)];

		WideCharToMultiByte(CP_ACP, 0, str, -1, chRtn, iLen, NULL, NULL);

		strstr = chRtn;
	}
	catch (std::exception e)
	{
	}

	return strstr;
}

测试调用dll 用qt写的:

#include "Gui_test_dll.h"
#include<QSettings>
#include<string>

Gui_test_dll::Gui_test_dll(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	
	connect(ui.Btn_ReadImage, SIGNAL(pressed()), this, SLOT(Btn_ReadImage()));
	connect(ui.pushButton_add, SIGNAL(pressed()), this, SLOT(pushButton_add()));
	connect(ui.comboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(push_dllname(int)));
	connect(ui.tableInfo_3, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableInfo_3(QTableWidgetItem *)));
	ui.tableInfo_3->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);    //设置水平与垂直自适应宽高
	ui.tableInfo_3->verticalHeader()->setVisible(true); // 显示垂直表头
	ui.tableInfo_3->horizontalHeader()->setVisible(true);//显示水平表头
	ui.tableInfo_3->setColumnCount(2); //设置两列列表
	
}
//----------读取文件夹下的路径以及文件名称------
//---------显示文件夹名称------------
//---------依次显示文件夹下所有图片的名称----------
void Gui_test_dll::Btn_ReadImage()
{
	//----------获取文件夹下的图片名以及图片路径--------------------------
	QString pathname = QFileDialog::getExistingDirectory(
		this,
		tr("Open Directory"),
		"/home",
		QFileDialog::ShowDirsOnly
		| QFileDialog::DontResolveSymlinks);
	QDir dir(pathname);
	QDir dir1(pathname);
	if (!dir.exists())
		qDebug() << "Not File Exists" << endl;
	/*ui.lineEdit->setText(pathname);*/
	dir.setFilter(QDir::Files | QDir::NoSymLinks);
	dir1.setFilter(QDir::Files | QDir::NoSymLinks);
	QStringList filters, filters1;
	filters << QString("*.dll");
	filters1 << QString("*.ini");
	dir.setNameFilters(filters);
	dir1.setNameFilters(filters1);
	int dir_cout = dir.count();

	if (dir_cout <= 0)
		qDebug() << "Not dll Exists" << endl;

	for (int i = 0; i<dir_cout; i++)
	{
		QString file_name = dir[i];  //dll文件名称
		QString file_name1 = dir1[i];  //dll文件名称
		ui.comboBox->addItem(file_name);
		ui.comboBox_2->addItem(file_name1);
	}
	//关闭信号tableweight的信号槽防止后面在加载ini文件里的初始划列表的时候,触发后面修改ini文件的信号
	disconnect(ui.tableInfo_3, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableInfo_3(QTableWidgetItem *)));
}

void Gui_test_dll::push_dllname(int)
{
	int i = 0;
	QString string = ui.comboBox_2->currentText();    //获取当前的ini名称
	if (string !=QString::fromLocal8Bit("请选择"))
	{
		//关闭信号tableweight的信号槽防止后面在加载ini文件里的初始划列表的时候,触发后面修改ini文件的信号
		disconnect(ui.tableInfo_3, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableInfo_3(QTableWidgetItem *)));
		QSettings fileSetting(string, QSettings::IniFormat);
		QStringList str = fileSetting.allKeys();
		ui.tableInfo_3->setRowCount(str.length());  //要设置行数与ini文件中的内容行数一致
		foreach(QString key, str)  //输出到tableweight上
		{
			ui.tableInfo_3->setItem(i, 0, new QTableWidgetItem(key));
			ui.tableInfo_3->setItem(i, 1, new QTableWidgetItem(fileSetting.value(key).toString()));  //读里边对应的值,输出到table
			i++;
		}
		//------------当把整个ini文件的信息加载完成之后再链接信号---------------------------
		connect(ui.tableInfo_3, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableInfo_3(QTableWidgetItem *)));
	}
    
}
//-------添加参数-------------------------------
void Gui_test_dll::pushButton_add()
{
	typedef void(*Fun)(); //定义函数指针,以备调用
	QString string = ui.comboBox->currentText();
	//---------QString借助string转成char*-------------
	QString string1 = ui.lineEdit->text();  //读取要执行的函数名称
	std::string str = string1.toStdString();
	const char* ch = str.c_str();

	QLibrary mylib(string);   //声明所用到的dll文件
	QString FunName;
	if (mylib.load())              //判断是否正确加载
	{
		QMessageBox::information(NULL, "OK", "DLL load is OK!");
		Fun open = (Fun)mylib.resolve(ch);    //援引 add() 函数		
		if (open)                  //是否成功连接上 add() 函数
		{
			QMessageBox::information(NULL, "OK", "Link to Function is OK!");
			open();      //这里函数指针调用dll中的 add() 函数
		}
		else
		{
			QMessageBox::information(NULL, "NO", "Linke to Function is not OK!!!!");
		}		
	}
}
void Gui_test_dll::tableInfo_3(QTableWidgetItem *)
{
	QString string;
	QTableWidgetItem *item=ui.tableInfo_3->currentItem();
	string = item->text();
	/*QMessageBox::information(NULL, "OK", string);*/
	QString string1 = ui.comboBox_2->currentText();    //获取当前的ini名称
	QSettings fileSetting(string1, QSettings::IniFormat);
	/*int row, col;*/
	//------得出当前修改的item行列坐标-----------
	int row = item->row();
	int col = item->column();
	QTableWidgetItem *item1 = ui.tableInfo_3->item(row, col - 1);
	QString key = item1->text();
	fileSetting.setValue(key, string);	  //将修改的值写进对应的ini文件中
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值