C#调用C++动态链接库


本文主要参考网络资源,<<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();
        }
    }
}

输出结果如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aboklh/article/details/85237517