本文主要参考网络资源,<<visual c++宝典>>,<<C#入门经典>>
1. 准备工作
1. 用vc做一个静态链接库
建立一个静态链接库
添加头文件 SampleLib.h
//SampleLib.h
/** \brief n1+n2
* \param n1 第一个加数
* \param n2 第二个加数
* \return 返回整型结果
*/
int addition(int n1, int n2);
添加源文件 SampleLib.cpp
#include "stdafx.h"
#include "SampleLib.h"
int addition(int n1, int n2)
{
return (n1 + n2);
}
这时会在工程目录的Debug文件夹中找到 SampleLib.lib 文件
2. 用vc调用静态链接库
新建一个控制台应用程序,来调用上面写的静态库, 注意: 调用静态库要把上面的 SampleLib.lib放在当恰工程目录下,我在工程目录下新建了一个libs文件夹,来专门放函数库文件. 同时, 还要把上面生成的头文件SampleLib.h拷贝过来, 并添加到工程当中. 如图
实现代码如下:
#include "stdafx.h"
#include "SampleLib.h" //调用函数库的头文件
#pragma comment (lib,"libs/SampleLib.lib") //调用函数库,第二个是.lib文件放置的相对路径
int main()
{
int sum;
sum = addition(3,2);
printf("%d\n", sum);
return 0;
}
输出结果是 5
3. 生成一个动态链接库
由于,生成dll文件时要对导出函数声明,而调用dll文件时又要重新对调用的函数再声明一次,因此,用条件编译的方式,将其一次性写出来,这样用的时候就不用重新定义(此处参考了<<visual c++ 宝典>>):
dll的头文件 ShowDlg.h
//声明导出函数
#include "StdAfx.h"
#ifndef SHOWDLG_H
#define SHOWDLG_H
extern"C" //此处代表按c风格编译,避免c++独特的编译方式,是的函数名发生改变
{
#define DLLMODLE_FUNCTIONTYPE __declspec(dllexport) //导出函数,声明dll的导出函数时,编译此处
//声明导出函数
DLLMODLE_FUNCTIONTYPE int mul(int a, int b); //声明导出函数,两数相乘
DLLMODLE_FUNCTIONTYPE int div(int a, int b); //导出函数,a/b
}
#endif
定义文件 ShowDlg.cpp
#include "StdAfx.h"
#include "ShowDlg.h"
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a/b;
}
编译成功后会在Debug文件夹中生成一个SampleDll.dll文件和SampleDll.lib
2. 用vc调用动态链接库
还是用第二部分设计的函数来调用dll文件,把ShowDlg.h拷贝到工程目录下,把SampleDll.dll文件和SampleDll.lib拷贝到libs文件夹中
头文件
#include "stdafx.h"
#include "SampleLib.h" //调用函数库的头文件
#pragma comment (lib,"libs/SampleLib.lib") //调用函数库,第二个是.lib文件放置的相对路径
#include "ShowDlg.h"
#pragma comment (lib,"libs/SampleDll.lib")
extern"C"
{
__declspec(dllimport) int mul(int a, int b); //声明导出函数,两数相乘
__declspec(dllimport) int div(int a, int b); //导出函数,a/b
}
int main()
{
int sum;
sum = addition(3,2);
printf("%d\n", sum);
sum = mul(3,4);
printf("%d\n", sum);
return 0;
}
这样还不行,因为默认查找dll文件的路径是 C:\Windows\System32,要在projct->setting中进行如下设置
运行结果
3. 用C#调用C++动态链接库
编写C#的demo,在visual stodio2017中新建一个C#语言的控制台应用程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ccproject1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello world");
Console.ReadLine();
}
}
}
这是一个输出 hello world 的简单控制台应用程序,它的工程启动目录是: 工程名\bin\Debug 这个路径待会要用到
现在添加引入DLL文件的语句:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//加入下面的引用,DllImport在该命名空间内
using System.Runtime.InteropServices;
namespace ccproject1
{
class Program
{
[DllImport("../SampleDll.dll")] //引入dll文件,注意:引号内的是文件路径
//"SampleDll.dll" 为默认路径C:\Windows\System32
//"/SampleDll.dll" 这是当前工程的启动目录,也就是前文提到的工程名\bin\Debug
//"../SampleDll.dll" ..代表上一级目录,也就是dll文件放在了Debug文件夹下
//路径可以用"\",不过由于"\"的特殊性,应用两个如:"..\\SampleDll.dll"
public extern static int mul(int a1, int b1); //声明要调用的函数,该函数返回a1*a2的值
static void Main(string[] args)
{
int c = 0;
c = mul(3, 4);
Console.WriteLine(c);
Console.ReadLine();
}
}
}
输出结果如下