C#调用c++的dll方法,动态调用c++dll的方法

news2024/12/26 23:05:20

文章目录

  • 一、创建c++的dll
    • 1.新建项目
    • 2.删除vs自建的.cpp和.h文件
    • 3.新建Algorithm.h和Algorithm.cpp
    • 4.编译c++
      • 1.编译
      • 2.解决报错
      • 3.再次编译可以看到已经成功。
      • 4.查看成功输出的dll。
  • 二、创建c#项目
    • 1.创建一个console控制台程序。
    • 2.把dll拷贝到c#生成的程序根目录。
    • 3.在c#的program.cs类引入命名空间System.Runtime.InteropServices。
  • 三、进阶,使用动态路径来调用c++的dll
    • 1.新建一个DLLWrapper类。
    • 2.在program.cs调用这个类
  • 项目下载链接


一、创建c++的dll

1.新建项目

右键解决方案>>添加>>新建项目
在这里插入图片描述
选择c++,windows,库,然后选择动态链接库
在这里插入图片描述
然后输入项目名称

在这里插入图片描述

2.删除vs自建的.cpp和.h文件

在这里插入图片描述

3.新建Algorithm.h和Algorithm.cpp

在这里插入图片描述
在这里插入图片描述
在Algorithm.h里面写上两个函数 add,munis
pragma关键字防止,h被重复引用
extern “C” __declspec(dllexport) 声明使用c的标准调用

#pragma once
#include <stdio.h>
extern "C" __declspec(dllexport) const char* Getversion();
extern "C" __declspec(dllexport) int add(int a, int b);
extern "C" __declspec(dllexport) int minus(int a, int b);

在项目的源文件下面按照上面的方法新建一个Algorithm.cpp文件,新建的文件如图。

在这里插入图片描述

代码如下:

#include "Algorithm.h"

const char* Getversion()
{
	return "v1.0.0";
}

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

int minus(int a, int b)
{
	return a - b ;
}

4.编译c++

1.编译

1.此时右键编译的时候会报错,提示 "严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C1010 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include “pch.h””? Testdll C:\Users\admin\Desktop\TestSystem\Testdll\Algorithm.cpp 17
" 错误列表如图:
在这里插入图片描述
输出如图:
在这里插入图片描述

2.解决报错

右键项目》》属性》》C/C++》》预编译头,改成如图配置。点击应用
在这里插入图片描述

3.再次编译可以看到已经成功。

在这里插入图片描述

4.查看成功输出的dll。

在这里插入图片描述

二、创建c#项目

1.创建一个console控制台程序。

在这里插入图片描述
之后选择c#,windows,控制台。
在这里插入图片描述
在这里插入图片描述
创建好之后先点击生成c#程序,确认没有问题,进行下一步

2.把dll拷贝到c#生成的程序根目录。

在这里插入图片描述

3.在c#的program.cs类引入命名空间System.Runtime.InteropServices。

添加如下代码:
在这里插入图片描述
完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static int add(int a, int b);
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static int minus(int a, int b);
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static IntPtr Getversion();
        
        static void Main(string[] args)
        {
            Console.WriteLine(add(1,5));
            Console.WriteLine(minus(1, 5));

            IntPtr pStr = Getversion();
            string version = Marshal.PtrToStringAnsi(pStr);
            Console.WriteLine(version);

            Console.ReadKey();
        }
    }
}

运行如图:
在这里插入图片描述

三、进阶,使用动态路径来调用c++的dll

这样做的好处是,dll不用放到exe的根目录,可以自己放到任何地方,方便管理。

1.新建一个DLLWrapper类。

代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    public class DLLWrapper
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeLibrary(IntPtr hModule);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetDllDirectory(string lpPathName);

        IntPtr pDll = IntPtr.Zero;
        public bool LoadDynamicLibrary(string path,string dlname)
        {
            if (File.Exists(Path.Combine(path, dlname)))
            {

                SetDllDirectory(path);
                pDll = LoadLibrary(dlname);

                if (pDll == IntPtr.Zero)
                {
                    Console.WriteLine("Failed to load DLL");
                    return false;
                }
                else
                {
                    Console.WriteLine("load DLL success");
                    return true;
                }
            }
            else
            {
                Console.WriteLine("DLL is not exist");
                return false;
            }
        }
        public bool FreeDllIntPtr()
        {
            bool resultFree = FreeLibrary(pDll);
            if (resultFree)
            {
                Console.WriteLine("DLL successfully unloaded.");
                return true;
            }
            else
            {
                Console.WriteLine("Failed to unload DLL.");
                return false;
            }
        }
    }
}


文件结构如图:
在这里插入图片描述

2.在program.cs调用这个类

区别如图:
在这里插入图片描述

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static int add(int a, int b);
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static int minus(int a, int b);
        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]
        extern static IntPtr Getversion();
        static void Main(string[] args)
        {
            DLLWrapper Wrapper = new DLLWrapper();
            //加载dll,传入dll的文件夹路径
            Wrapper.LoadDynamicLibrary(Environment.CurrentDirectory+ "\\Library", "Testdll.dll");

            Console.WriteLine(add(1,5));
            Console.WriteLine(minus(1, 5));

            IntPtr pStr = Getversion();
            string version = Marshal.PtrToStringAnsi(pStr);
            Console.WriteLine(version);

            //释放dll
            Wrapper.FreeDllIntPtr();
            Console.ReadKey();
        }
    }
}

运行如图:
在这里插入图片描述
源码链接如下:没有积分的可以留言给我,发送个人邮箱

项目下载链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995595.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF自定义控件的应用(DynamicResource的使用方法)

1 DynamicResource的使用方法 可以在字典文件 的抬头区写入数&#xff1a; <SolidColorBrush x:Key"PrimaryBackgroundColor" Color"#FFABAdB3"/><SolidColorBrush x:Key"TextBox.MouseOver.Border" Color"#FF7EB4EA"/>&l…

得-物任务脚本

得某物任务脚本 该脚本主要用于自动化执行“得物”APP中的一些日常任务和活动&#xff0c;包括签到、任务完成、奖励领取等操作。使用了多个第三方库来加密、签名和发送请求。 任务的定时执行 脚本通过定时任务&#xff08;cron&#xff09;设置在每天的11:10执行。使用的依…

通用人工智能的中国道路

朱松纯 北京大学智能学院院长 北京大学人工智能研究院院长 《为机器立心》、《为人文赋理》 1 什么是“人”——解构人文的认知架构与UV理论 从物体&#xff0c;到生命体、智能体、智人。。。 生命度&#xff08;Animacy&#xff09;&#xff1a;物体与智能体的边界&#xff0…

LLC数字控制TMS320F28034,4-DSP的epwm配置介绍

LLC数字控制TMS320F28034&#xff0c;4-DSP的epwm配置介绍 1 TMS320F280341.1 概述1.2 PWM详细介绍 2 TMS320F28034 PWM功能框图2.1 ePWM功能模块2.2 ePWM功能寄存器框图 3 TMS320F28034 PWM初始化流程4 结合项目设计5 代码设计5.1 PWM初始化程序5.2 工程代码 6 总结 配套代码示…

OpenCV图像滤波(9)getGaussianKernel()函数的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 功能描述 cv::getGaussianKernel() 是 OpenCV 中的一个函数&#xff0c;用于生成一维高斯核。这种核通常用于实现高斯模糊滤波器&#xff0c;该滤波器可以…

系统编程 day6 文件5

今天编写小程序实现minishell&#xff08;简易版文件操作命令函数编写以及实现&#xff09; 编写过程&#xff0c;以及部分代码展示 终端实现minishell部分功能展示

fastadmin 实现标签打印

项目场景如图&#xff0c;需要打印一批条形码或者二维码&#xff0c;除了市面上成熟的标签机之外&#xff0c;今天挑战一下使用普通的打印机不干胶贴纸&#xff0c;实现低成本的标签打印&#xff1b; 项目框架基于 fastadmin&#xff1a; 1、项目对应的js添加打印按钮的事件监…

C语言指针详解-包过系列(二)目录版

C语言指针详解-包过系列&#xff08;二&#xff09;目录版 1、数组名的深入理解1.1、数组名的本质1.2、数组名本质的两个例外1.2.1、sizeof&#xff08;数组名&#xff09;1.2.2、&数组名 2、使用指针访问数组3、一维数组传参本质4、二级指针4.1、二级指针介绍4.2、二级指针…

5个国内大厂的AI写真神器,连影楼老板都在用!看看你用过几个

大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~ 如果你的女朋友再缠着你&#xff0c;要你陪她去拍写真&#x…

kickstart自动脚本制作

克隆7主机&#xff0c;配置网络 安装图形 yum group install "Server with GUI" -y 有的话直接切换 init 5 关闭 Vmware dhcp 安装图形化生成kickstar自动安装脚本的工具 yum install system-config-kickstart -y 配置http 安装 yum install httpd -y 启动服务…

Advanced IP Scanner - 网络扫描工具介绍

Advanced IP Scanner 是一款免费、快速且用户友好的网络扫描工具。它能够帮助用户扫描局域网&#xff08;LAN&#xff09;中的所有设备&#xff0c;提供详细的设备信息&#xff0c;包括IP地址、MAC地址、设备名称和厂商信息。该工具对IT管理员和普通用户都非常有用&#xff0c;…

CMake内置模块

2024年8月9日&#xff0c;周五晚上 很久没写博客了&#xff0c;主要是最近很长一段时间都在备考研究生 简介 CMake附带了一系列内置模块&#xff0c;这些模块提供了许多常用的功能和宏&#xff0c;以帮助用户在构建项目时完成各种任务。 CMake的内置模块有哪些&#xff1f; …

解锁创意之门:如何使用DALL·E-3创作惊艳的图像

在这个视觉驱动的时代&#xff0c;图像已经成为表达创意和传递信息的重要媒介。最近&#xff0c;OpenAI发布了新一代的图像生成模型——DALLE-3&#xff0c;它以其卓越的生成能力和细致的图像质量迅速成为了创意工作者的热门工具。今天&#xff0c;我将带你一步步了解如何使用D…

springboot中小型酒店管理系统02793

摘要 随着互联网和移动技术的快速发展&#xff0c;酒店行业也面临着巨大的变革和机遇。传统的酒店管理方式存在着信息不透明、预订流程繁琐等问题&#xff0c;无法满足现代消费者对便捷、高效、个性化服务的需求。因此&#xff0c;开发中小型酒店管理系统具有重要的意义。本文旨…

[论文阅读]Mobility-Aware Cooperative Caching in VEC Based on CAFR

论文&#xff1a;Mobility-Aware Cooperative Caching in Vehicular Edge Computing Based on Asynchronous Federated and DRL JSTSP 2022 基于异步联邦和深度强化学习的车载边缘计算移动感知协同缓存 一、Introduction background&#xff1a; 随着车联网&#xff08;IoV&…

数据结构--单链

#include "link.h" plink get_head() { plink pmalloc(sizeof(Link)); if(pNULL) { printf("申情节点失败\n"); return NULL; } p->len0; p->nextNULL; return p; } void head_insert(plink L,int a) {…

AI动漫生成工具,文生图转换图生视频功能,低成本使用AI工具做项目。AI工具搭建开发。

目录 前言&#xff1a; 一、AI文生动漫有哪些功能&#xff1f; 二、如何低价使用AI工具&#xff1f; 三、AI工具适合现在做哪些互联网项目&#xff1f; 总结&#xff1a; 前言&#xff1a; AI动漫原理就是通过文字描述来生成图片&#xff0c;然后对文本配上语音和音乐生成…

[极客大挑战 2019]FinalSQL1

打开题目 sql注入&#xff0c;点击1试一下 点击2试一下 点击3试一下 点击4 点击5 id6试一下 感觉是sql盲注了 编写脚本 import requests import string from time import sleep url "http://9da9cb18-3096-413a-9476-8a177ffec31a.node4.buuoj.cn:81/search.php?id0^(…

陶瓷材质的防静电架空地板越来越受欢迎的原因

目前市面上的陶瓷防静电架空地板主要分为两种&#xff1a;钢基和硫酸钙基。前者是以全钢冲孔裸板作为板基&#xff0c;经粘接、固定整型和灌浆的方式加工而成&#xff0c;后者是以复合硫酸钙板为基材&#xff0c;表面粘接防静电陶瓷砖&#xff0c;四周导电PVC边条封边。近年来陶…

【网络】套接字socket编程预备知识

1.源IP地址和目的IP 计算机网络中的源地址和目的地址是用来标识网络中的不同主机的。 源地址是指发送数据包的主机的地址&#xff0c;而目的地址则是指接收数据包的主机的地址&#xff0c;在数据包传输过程中&#xff0c;每经过一个路中器感交换机&#xff0c;都会根据目的地址…