Window系统c++动态静态调用案例

       在进行实际项目时,有时候需要使用别人封装好的dll,或者自己编写的封装好的dll,本文从实际使用的角度出发,在VS环境下,使用c++语言编写了同时调用三个dll的调用函数以及其dll的生成函数。

一、firstDll

该dll封装了一个简单加法函数,配合使用静态调用的方法,如下为代码部分

1、使用VS创建一个空项目,在空项目下创建一个cpp文件和一个h头文件

2、cpp文件写加法函数的函数体,并且引用h头文件

#include"firstDll.h"



int __stdcall  add(int a, int b)
{
	return a + b;
}

3、h文件写一个接口,内部声明一些结构体定义以及函数

#pragma once


#ifdef __cplusplus			// 一般用于将C++代码以标准C形式输出(即以C的形式被调用)

extern"C" {			// 告诉编译器下面大括号括起来的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)
#endif

	__declspec(dllexport) int __stdcall  add(int a, int b);      // __declspec(dllexport)声明导出该函数供外部调用

// __stdcall是Windows API默认的函数调用协议,函数采用从右到左的压栈方式,自己在退出时清空堆栈,也可以不使用

#ifdef __cplusplus
}
#endif

4、修改属性中的输出,将exe改为动态库dll

5、生成解决方案后,即可找到dll、exp、lib、pdb四个类型的文件

此时便完成了dll的制作

二、secondDll

该dll封装了一个简单的调用scip求解混合整数规划问题的方法,配合使用静态调用的方法,如下为代码部分

1、需要按要求配置scip求解器

2、cpp文件写加法函数的函数体,并且引用h头文件

#include <iostream>
#include"secondDll.h"
#include <scip/scipdefplugins.h>

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

res _stdcall mipTest()
{
	res ret;

	// creates and initializes SCIP data structures
	SCIP* _scip;
	SCIPcreate(&_scip);

	// include default plugins
	SCIPincludeDefaultPlugins(_scip);

	// creates empty problem and initializes all solving data structures
	SCIPcreateProbBasic(_scip, "test");

	//sets objective sense of problem
	SCIPsetObjsense(_scip, SCIP_OBJSENSE_MINIMIZE);

	// changes the value of an existing SCIP_Real parameter
	SCIPsetRealParam(_scip, "limits/gap", 0.00001);
	SCIPsetRealParam(_scip, "limits/time", 10);

	//--添加变量
	SCIP_VAR* xVar = nullptr;
	SCIPcreateVarBasic(_scip, &xVar, "_x", 0, SCIPinfinity(_scip), 2.0, SCIP_VARTYPE_INTEGER);
	SCIPaddVar(_scip, xVar);

	SCIP_VAR* yVar = nullptr;
	SCIPcreateVarBasic(_scip, &yVar, "_y", 0, SCIPinfinity(_scip), 3.0, SCIP_VARTYPE_INTEGER);
	SCIPaddVar(_scip, yVar);

	//--添加约束
	SCIP_CONS* zCons;
	SCIPcreateConsBasicLinear(_scip, &zCons, "z_cons", 0, NULL, NULL, 7, SCIPinfinity(_scip));
	SCIPaddCoefLinear(_scip, zCons, xVar, 2);
	SCIPaddCoefLinear(_scip, zCons, yVar, 3);
	SCIPaddCons(_scip, zCons);

	SCIPsolve(_scip);

	//--取最优解
	SCIP_Real x_value = SCIPgetSolVal(_scip, SCIPgetBestSol(_scip), xVar);
	SCIP_Real y_value = SCIPgetSolVal(_scip, SCIPgetBestSol(_scip), yVar);

	//--释放资源
	SCIPreleaseVar(_scip, &xVar);
	SCIPreleaseVar(_scip, &yVar);

	SCIPreleaseCons(_scip, &zCons);

	SCIPfree(&_scip);

	std::cout << "x_value: " << x_value << std::endl;
	std::cout << "y_value: " << y_value << std::endl;

	ret.x = x_value;
	ret.y = y_value;

	return ret;
}

3、h文件写一个接口,内部声明一些结构体定义以及函数

#pragma once

struct res
{
	int x;
	int y;
};


extern "C" _declspec(dllexport) res _stdcall mipTest();

4、按照上面的方法生成四个文件

三、thirdDll

该dll封装了一个简单的减法函数,配合使用动态调用的方法,如下为代码部分

1、cpp部分

#pragma once
#include"thirdDll.h"



int __stdcall  subec(int a, int b)
{
	return a - b;
}

2、h部分


#pragma once


#ifdef __cplusplus												// 一般用于将C++代码以标准C形式输出(即以C的形式被调用)
extern"C" {			// 告诉编译器下面大括号括起来的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)
#endif

	__declspec(dllexport) int __stdcall  subec(int a, int b);      // __declspec(dllexport)声明导出该函数供外部调用

// __stdcall是Windows API默认的函数调用协议,函数采用从右到左的压栈方式,自己在退出时清空堆栈,也可以不使用

#ifdef __cplusplus
}
#endif

3、编译生成四个文件

四、本章节介绍如何调用上面生成的四个dll方法

1、创建一个空项目,写好主函数并运行一次(目的是生成exe的根目录)

2、将以上生成的dll放到exe目录下,将lib放到函数体目录下

3、每个dll都有一个h文件,内容与dll中的类似,目的是声明dll中输入输出的类与结构体、函数等

4、h文件

firstDll.h
#pragma once
//本dll为一个简单的加法函数   


// 这里使用__declspec(dllimport),正好和生成dll时的__declspec(dllexport)对应
// 生成dll时没有加__stdcall的话,这里也不用加

#pragma comment(lib, "firstDll.lib")                                     // 告诉程序lib文件的路径,这里就表示当前目录
extern "C" __declspec(dllimport) int __stdcall add(int a, int b);       
secondDll.h
#pragma once
//本dll为一个scip编写简单线性规划的DLL  


// 这里使用__declspec(dllimport),正好和生成dll时的__declspec(dllexport)对应
// 生成dll时没有加__stdcall的话,这里也不用加

#pragma comment(lib, "secondDll.lib")                                     // 告诉程序lib文件的路径,这里就表示当前目录

struct res
{
	int x;
	int y;
};
extern "C" __declspec(dllimport) res __stdcall mipTest();

secondDll使用动态调用,因此可以不需要头文件,但是结构体之类如果存在还是需要

5、cpp

#include <iostream>
#include"firstDll.h"
#include"second.h"
#include<windows.h>

using namespace std;




int main()
{
	cout << "====================================firstDll调用  加法函数   使用静态调用===========================================" << endl;
	int a = 3;
	int b = 2;
	std::cout << "add result is: " << add(a, b) << std::endl;

	cout << "=====================================secondDll调用  scip求简单线性规划   使用静态调用================================" << endl;
	std::cout << "mip x result is: " << mipTest().x << " ,mip y result is: " << mipTest().y << std::endl;


	cout << "====================================firstDll调用  减法函数   使用动态调用===========================================" << endl;
    // 动态调用DLL库
	// 运行时加载DLL库
	HMODULE module = LoadLibraryA("thirdDll.dll");     // 根据DLL文件名,加载DLL,返回一个模块句柄
	if (module == NULL)
	{
		printf("加载thirdDll.dll动态库失败\n");
	}
	typedef int(*subFunc)(int, int);                  // 定义函数指针类型
	subFunc sub;
	// 导出函数地址
	sub = (subFunc)GetProcAddress(module, "subec");     // GetProcAddress返回指向的函数名的函数地址

	int sum = sub(100, 200);
	printf("动态调用,subec = %d\n", sum);


	system("pause");
	return 0;
}

6、运行结果

====================================firstDll调用  加法函数   使用静态调用===========================================
add result is: 5
=====================================secondDll调用  scip求简单线性规划   使用静态调用================================
feasible solution found by trivial heuristic after 0.0 seconds, objective value 5.000000e+05
presolving:
(round 1, fast)       0 del vars, 0 del conss, 0 add conss, 4 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs
   (0.0s) running MILP presolver
   (0.0s) MILP presolver found nothing
(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 4 chg bounds, 0 chg sides, 0 chg coeffs, 1 upgd conss, 0 impls, 0 clqs
   (0.0s) symmetry computation started: requiring (bin +, int +, cont +), (fixed: bin -, int -, cont -)
   (0.0s) no symmetry present (symcode time: 0.00)
presolving (3 rounds: 3 fast, 2 medium, 2 exhaustive):
 0 deleted vars, 0 deleted constraints, 0 added constraints, 4 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
 0 implications, 0 cliques
presolved problem has 2 variables (0 bin, 2 int, 0 impl, 0 cont) and 1 constraints
      1 constraints of type <varbound>
transformed objective value is always integral (scale: 1)
Presolving Time: 0.00

 time | node  | left  |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr|  dualbound   | primalbound  |  gap   | compl.
t 0.0s|     1 |     0 |     0 |     - | trivial|   0 |   2 |   1 |   0 |   0 |  0 |   0 |   0 | 7.000000e+00 | 1.700000e+01 | 142.86%| unknown
p 0.0s|     1 |     0 |     0 |     - | vbounds|   0 |   2 |   1 |   0 |   0 |  0 |   0 |   0 | 7.000000e+00 | 9.000000e+00 |  28.57%| unknown
p 0.0s|     1 |     0 |     0 |     - | vbounds|   0 |   2 |   1 |   0 |   0 |  0 |   1 |   0 | 7.000000e+00 | 8.000000e+00 |  14.29%| unknown
* 0.0s|     1 |     0 |     0 |     - |    LP  |   0 |   2 |   0 |   0 |   0 |  0 |   2 |   0 | 7.000000e+00 | 7.000000e+00 |   0.00%| unknown
  0.0s|     1 |     0 |     0 |     - |   583k |   0 |   2 |   0 |   0 |   0 |  0 |   2 |   0 | 7.000000e+00 | 7.000000e+00 |   0.00%| unknown

SCIP Status        : problem is solved [optimal solution found]
Solving Time (sec) : 0.00
Solving Nodes      : 1
Primal Bound       : +7.00000000000000e+00 (5 solutions)
Dual Bound         : +7.00000000000000e+00
Gap                : 0.00 %
x_value: 2
y_value: 1
feasible solution found by trivial heuristic after 0.0 seconds, objective value 5.000000e+05
presolving:
(round 1, fast)       0 del vars, 0 del conss, 0 add conss, 4 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs
   (0.0s) running MILP presolver
   (0.0s) MILP presolver found nothing
(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 4 chg bounds, 0 chg sides, 0 chg coeffs, 1 upgd conss, 0 impls, 0 clqs
   (0.0s) symmetry computation started: requiring (bin +, int +, cont +), (fixed: bin -, int -, cont -)
   (0.0s) no symmetry present (symcode time: 0.00)
presolving (3 rounds: 3 fast, 2 medium, 2 exhaustive):
 0 deleted vars, 0 deleted constraints, 0 added constraints, 4 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
 0 implications, 0 cliques
presolved problem has 2 variables (0 bin, 2 int, 0 impl, 0 cont) and 1 constraints
      1 constraints of type <varbound>
transformed objective value is always integral (scale: 1)
Presolving Time: 0.00

 time | node  | left  |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr|  dualbound   | primalbound  |  gap   | compl.
t 0.0s|     1 |     0 |     0 |     - | trivial|   0 |   2 |   1 |   0 |   0 |  0 |   0 |   0 | 7.000000e+00 | 1.700000e+01 | 142.86%| unknown
p 0.0s|     1 |     0 |     0 |     - | vbounds|   0 |   2 |   1 |   0 |   0 |  0 |   0 |   0 | 7.000000e+00 | 9.000000e+00 |  28.57%| unknown
p 0.0s|     1 |     0 |     0 |     - | vbounds|   0 |   2 |   1 |   0 |   0 |  0 |   1 |   0 | 7.000000e+00 | 8.000000e+00 |  14.29%| unknown
* 0.0s|     1 |     0 |     0 |     - |    LP  |   0 |   2 |   0 |   0 |   0 |  0 |   2 |   0 | 7.000000e+00 | 7.000000e+00 |   0.00%| unknown
  0.0s|     1 |     0 |     0 |     - |   583k |   0 |   2 |   0 |   0 |   0 |  0 |   2 |   0 | 7.000000e+00 | 7.000000e+00 |   0.00%| unknown

SCIP Status        : problem is solved [optimal solution found]
Solving Time (sec) : 0.00
Solving Nodes      : 1
Primal Bound       : +7.00000000000000e+00 (5 solutions)
Dual Bound         : +7.00000000000000e+00
Gap                : 0.00 %
x_value: 2
y_value: 1
mip x result is: 2 ,mip y result is: 1
====================================firstDll调用  减法函数   使用动态调用===========================================
动态调用,subec = -100
请按任意键继续. . .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值