C# 使用C/C++动态链接库(dll) ——简单应用

需求

在日常开发中,偶然间就会使用C/C++编写的动态链接库。那么如何在C#中调用和使用C/C++动态链接库的函数呢?

Melphi使用C/C++编写了一个AddCount()方法,用于计算两个传入参数的和,并返回给调用者。

 

环境

Windows 10

Visual Studio 2017

平台工具集:Visual Studio 2017 (v141)

 

实现

C/C++动态链接库

  • 新建一个动态链接库的项目,命名为Melphi.Test

  • 打开新建的项目,添加Melphi.Test.h头文件

  • 打开Melphi.Test.h头文件,并添加我们的Add函数,代码如下:
#pragma once

// 宏定义:说明通过 MelphiAPI 声明的函数为导出函数,供其他程序调用,作为动态库的对外接口函数
#define MelphiAPI _declspec(dllexport) _stdcall

// 传递两个参数(int),获取计算的结果(int)
extern "C" int MelphiAPI Add(int a, int b);
  • 打开Melphi.Test.cpp文件,添加Add函数的实现,代码如下:
// Melphi.Test.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#include "MelphiTest.h"

// 获取两个 int 值的和
int MelphiAPI Add(int a, int b)
{
	return a + b;
}

到此,我们的动态链接库的函数就写好了,接下来,我们使用我们熟悉的C#来调用这个函数。

C# DllImport

 

为了方便我们代码的管理,我们将所有的导入函数都统一定义到DllImportCore.cs的文件中。

C#当然不能直接使用动态链接库中的函数,我们需要通过.NETFramework里面提供的DllImport来帮我制造一个连接动态链接库中函数的入口点,需要使用到的命名空间:System.Runtime.InteropServices

  • 函数入口的声明定义,代码如下:
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Melphi
{ 
    public class DllImportCore
        {
            /// <summary>
            /// 求和 传入参数(C++ int == C# int)
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            [DllImport("cpplib/Melphi.Test.dll", EntryPoint ="Add", CallingConvention = CallingConvention.StdCall)]
            public static extern int Add(int a, int b);
        }
}
  • DllImport中参数说明

cpplib/Melphi.Test.dll:表示我们动态链接库的 DLL 名称,这里使用了相对路径标识。它是特性DllImportAttribute的构造器(函数)需要传递和指定的参数,称为定位参数,是强制性的——应用这个特性时,必须指定这个参数。

EntryPoint ="AddCount":表示我们定义的函数入口点的名称,也就是动态链接库中我们需要调用函数的名称。它是特性DllImportAttribute的公共实例字段,它是用于设置字段的参数,称为命名参数,这个参数是可选的——应用这个特性时,不一定要指定参数。

CallingConvention = CallingConvention.StdCall:指示入口点的调用规约,这里使用默认规约。它是特性的一个命名参数

  • 函数的调用

在我们定义的时候,函数变成静态的函数。因此在调用的时候,按照调用静态方法的形式去调用即可。下面是在WPF中的App类的OnStartup方法内调用。

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;

namespace Melphi
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Console.WriteLine("2+2=" + DllImportCore.Add(2, 2));
            
			Console.ReadKey();
        }
    }
}

And then,the coding work is completed.Next,we will to build and debug it.

 

运行

在运行之前 ,我们需要编译程序。前面我们知道,C#调用的动态链接库的路径在C#运行程序的当前目录下的cpplib文件夹中,因此,我们需要将我们的动态链接库编译到该文件夹中(也可以直接编译之后,直接将DLL拷贝过去)。

  • 动态链接库的编译属性配置

需要将项目的输出目录修改到我们需要它生成的目标文件夹即可。

操作:项目(Melphi.Test)-->右键-->属性;配置属性-->常规-->输出目录-->浏览--(找到目标文件夹)-->点击确定。

  • 生成动态链接库

生成成功之后,可以检查下文件是否成功赋值到我们需要的目录下。

  • F5启动

在启动之前,需要将C#项目Melphi设为启动项。

由于我们需要看Console输出的内容,所以需要将项目的属性的输出类型设置为控制台应用程序

  • 结果

 

总结

本文主要用于记录如何使用C#调用动态链接库。后续会丰富对各种数据类型的函数调用以及指针的介绍和使用。

 

Over

每次记录一小步...点点滴滴人生路...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值