VS2017下创建C++动态库导出符合并完成调用测试(DLL可供C#调用)

简介: VS2017下创建C++动态库导出符合并完成调用测试(DLL可供C#调用)

一、环境介绍

VS版本:  VS2017

编程语言: C++

二、功能介绍

使用VS2017项目模板创建C++动态库生成工程,生成动态库。然后再创建一个C++工程调用动态库完成测试。

三、创建动态库

image.png

工程创建之后,VS会自动生成一个示例模板;下面截图里是将VS自动生成的模板代码给删除掉了,添加自己编写了2个测试函数。

image.png

#ifdef DLLLIBRARY_EXPORTS
#define DLLLIBRARY_API __declspec(dllexport)
#else
#define DLLLIBRARY_API __declspec(dllimport)
#endif
EXTERN_C DLLLIBRARY_API char* Version(void);
EXTERN_C DLLLIBRARY_API int sum(int a, int b);

image.png

static char version_str[] = "v20210524";
// 获取版本号
DLLLIBRARY_API char* Version(void)
{
  return version_str;
}
// 求和
DLLLIBRARY_API int sum(int a, int b)
{
  int c = a + b;
  return c;
}

写好之后,编译生成动态库。

image.png

image.png

生成的库文件在解决方案目录下:

image.png

四、创建C++工程调用动态库

image.png

将第一步生成的库文件xxx.lib拷贝到当前测试工程目录下:

image.png

编写调用库的测试代码:

image.png

#include <iostream>
#pragma comment(lib, "DLLLIBRARY.lib")
extern "C"
{
  extern __declspec(dllexport) char* Version(void);
  extern __declspec(dllexport) int sum(int a, int b);
};
using namespace std;
int main()
{
  int c = sum(12, 34);
  cout << "求和:" << c << endl;
  char *p = Version();
  cout << "版本号:" << p;
}

写完代码后,直接编译运行,会报错提示缺少xxx.dll,接下来把xxx.dll拷贝到程序运行目录下即可。

image.png

拷贝xxx.dll到程序运行目录下:

image.png

再次编译运行:

image.png

五、C#调用动态库测试

创建一个C#控制台工程,准备调用DLL库测试。

image.png

编写调用库的测试代码:

image.png

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
    class Program
    {
        [DllImport("DLLLIBRARY.dll", EntryPoint = "sum", CallingConvention = CallingConvention.Cdecl)]
        extern static int sum(int a, int b);
        [DllImport("DLLLIBRARY.dll", EntryPoint = "Version",CharSet =CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static IntPtr Version();
        static void Main(string[] args)
        {
            Console.WriteLine(sum(100,200));
            Console.WriteLine(Marshal.PtrToStringAnsi(Version()));
            Console.ReadKey();
        }
    }
}

编译运行,提示无法加载xxx.dll,接下来将xxx.dll拷贝到程序运行目录下即可。

image.png

拷贝xxx.dll到当前程序运行目录下:

image.png

再次运行:

image.png

六、C#传入C指针字符串参数

如果C的函数需要传入字符串,C#可以这样传递:

C函数原型:

static char version_str[] = "v20210524";
//获取版本号
ECRSTOOLLIBRARY_API char* Version(void)
{
  return version_str;
}
void GetApplicationDirPath(char * buff)
{
  printf("传入的参数:%s\n", buff);
}

C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace CSharp_LoadLibrary
{
    class Program
    {
        [DllImport("ECRSTOOLLIBRARY.dll", EntryPoint = "Version", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static IntPtr Version();
        [DllImport("ECRSTOOLLIBRARY.dll", EntryPoint = "GetApplicationDirPath", CallingConvention = CallingConvention.Cdecl)]
        extern static void GetApplicationDirPath(IntPtr text);
        static void Main(string[] args)
        {
            //申请空间
            IntPtr pBuff = Marshal.AllocHGlobal(100);
            //将string转为IntPtr类型
            string str = "我是传递给C++的字符串";
            pBuff = Marshal.StringToHGlobalAnsi(str);
            //调用C++方法
            GetApplicationDirPath(pBuff);
            //释放空间
            Marshal.FreeHGlobal(pBuff);
            Console.WriteLine(Marshal.PtrToStringAnsi(Version()));
            Console.ReadKey();
        }
    }
}

image.png

目录
相关文章
|
6月前
|
存储 安全 算法
【C++智能指针 相关应用】深入探索C++智能指针:跨进程、动态库与最佳实践
【C++智能指针 相关应用】深入探索C++智能指针:跨进程、动态库与最佳实践
114 5
|
6月前
|
C#
C# 解决引用dll,出现dll不可以使用等问题
C# 解决引用dll,出现dll不可以使用等问题
|
6月前
|
数据处理 C# C++
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
286 0
|
2月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
1月前
|
C#
Delphi可不可以制作出像c#那样的dll类库?
在Delphi中,创建DLL项目(如dll.dpr)并定义一个类TMyCls后,在另一个项目(如test.dpr)中可以引入此DLL并直接实例化和调用类的方法。然而,Delphi目前主要支持两种DLL形式:动态链接库(需显式声明exports,仅支持函数调用)和ActiveX DLL(需定义IDL接口)。这两种方式都较为繁琐。相比之下,C# 的DLL类库更为便捷,编写并编译后即可在其他项目中直接使用。
|
2月前
|
Linux API C++
超级好用的C++实用库之动态库加载器
超级好用的C++实用库之动态库加载器
27 0
|
3月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
78 0
|
3月前
|
C# 图形学 数据安全/隐私保护
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
|
5月前
|
Java Go C#
编程语言C#、C++、Java、Python、go 选择哪个好?
我想说的是,不论选择哪种编程语言,决定选择的都是你最终的目的,做选择之前,先充分调研每一个选择项,再做选择思路就会非常清晰了。
119 3
|
5月前
|
安全 编译器 API
程序与技术分享:C#调用DLL的几种方法
程序与技术分享:C#调用DLL的几种方法
82 0