C#调用C动态链接库
前言
已经没写过博客好久了,上一篇还是1年半前写的LTE Gold序列学习笔记,因为工作是做通信协议的,然后因为大学时没好好学习专业课,现在理论还不扎实,不敢瞎写;
因为工作原因,经常需要分析一些字节流数据,所以基本都是用C写的,结果输出在命令行,或者txt/csv文件;但个人还是喜欢输出到GUI界面,可选的手段就MFC、WinForm、PyQt:
MFC的话感觉多少有点过时了,所以用WinForm,PyQt的多点,尤其是WinForm很方便;前段时间用WinForm写了个日志分析工具,因为本人是业余的C#使用者,所以写的很痛苦,至于数据处理的核心思想就CSDN上的结构体字节流的相互处理,数据处理部分大概1000来行;但工作中用的结构体通常很大,涉及大小端转换,同时还有位域,处理起来很麻烦,用C的话就很方便,所以用C处理数据用WinForm、PyQt显示的方法比较方便;所以就想着用C处理玩数据保存到txt/csv文件,然后用C#/Python去调用C应用并读取文件,但感觉有点low;所以就打算把C部分的处理输出成dll文件,然后用C#/Python去调用DLL;当然对我的需求来说,把所有数据封装到1个结构体里面,每个结构体字段是Uint或者Uint数组即可;以下部分实现就仅仅是能用即可,没具体设置;
C语言部分-编译生成动态链接库
我办公电脑上是VS2015,自己电脑是VS2017,创建工程有点差异;
VS2015工程设置使用CSDN上面的截图,注意源文件后缀用默认的cpp,不要用c,我还没去学习这块的细节,反正能用就行

VS2017生成控制台应用程序后,需要将如下红框中的配置类型修改为动态库;

然后代码和C应用程序的差异的话就在函数声明或定义前加上
extern "C" _declspec(dllexport) int add_test(int x, int y);
不设置配置和平台的话,默认输出就在Debug路径下生成和项目名一样的DLL文件,如下图:

C#部分-使用动态链接库
把编译生成的DLL文件放到C#编译输出的路径下,不配置的话就在如下路径:

在C#中调用C的话,核心代码就如下2行,
[DllImport("DLLTEST.dll",CallingConvention=CallingConvention.Cdecl)]
extern static int add_test(int x, int y);
还有需要注意的点,需要包含如下引用,当然写了如上第一行就会提示让包含了:
using System.Runtime.InteropServices;
感觉像是函数外部声明,能用就行,暂时没有去深究原理啥的,输出如下:

因为需要处理的数据通常比较多,所以就定义一个结构体,把需要传输的数据全放里面,然后用1个接口就读过去了;
简单做个测试
- C程序定义一个结构体,结构体里面仅包含一个字段,字段是一个Uint类型的数组:
typedef struct
{unsigned int data[32];
}RetData;
- C程序输出结构体数据测试:
void get_array(RetData* ret)
{for (int idx = 0; idx < 32; idx++){ret->data[idx] = idx * 10;}
}
- C#程序也定义一个结构体,结构体包含一个字段,字段是Uint32类型的数组:
struct GetData{[MarshalAs(UnmanagedType.ByValArray,SizeConst =32)]public UInt32[] data;}
-
C#程序读入结构体数据测试,可能用法很不专业,能读出来就行
/* 函数外部声明 */
[DllImport("DLLTEST.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void get_array(ref GetData ret);/* 在Main函数中调用 */
GetData getData = new GetData();
get_array(ref getData);
- 输出

今天下午在公司写了个维测工具,整个流程和上面测试步骤一致,能正常使用
Python部分-使用动态链接库
把编译生成的DLL文件放到Python文件同级路径下,这样在Python代码中就直接使用DLL文件名即可,Python测试代码如下,调用数组那块先前在公司测试正常能用来自,忘了,懒得写了
import ctypes
dll = ctypes.windll.LoadLibrary('DLLTEST.dll')
print(dll.add_test(4, 5))
输出5:如下图:

本来打算把整个工程打包放到CSDN来着,但免费的话审核不通过,所以就把C/C#部分代码都贴下面了:
C程序头文件
#pragma once
#ifndef DLL_TEST_H
#define DLL_TEST_Htypedef struct
{unsigned int data[32];
}RetData;extern "C" _declspec(dllexport) int add_test(int x, int y);
extern "C" _declspec(dllexport) void get_array(RetData* ret);#endif // !DLL_TEST_H
C程序源文件
#include <stdio.h>
#include <stdlib.h>
#include "dll_test.h"int add_test(int x, int y)
{return x + y;
}void get_array(RetData* ret)
{for (int idx = 0; idx < 32; idx++){ret->data[idx] = idx * 10;}
}
C#程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp1
{struct GetData{[MarshalAs(UnmanagedType.ByValArray,SizeConst =32)]public UInt32[] data;}class Program{[DllImport("DLLTEST.dll",CallingConvention=CallingConvention.Cdecl)]extern static int add_test(int x, int y);[DllImport("DLLTEST.dll", CallingConvention = CallingConvention.Cdecl)]extern static void get_array(ref GetData ret);static void Main(string[] args){Console.WriteLine("{0} + {1} = {2}", 4, 5, add_test(4, 5));GetData getData = new GetData();get_array(ref getData);Console.ReadLine();}}
}
相关文章:
C#调用C动态链接库
前言 已经没写过博客好久了,上一篇还是1年半前写的LTE Gold序列学习笔记,因为工作是做通信协议的,然后因为大学时没好好学习专业课,现在理论还不扎实,不敢瞎写; 因为工作原因,经常需要分析一些字…...
前端实现转盘抽奖 - 使用 lucky-canvas 插件
目录 需求背景需求实现实现过程图片示意实现代码 页面效果lucky-canvas 插件官方文档 需求背景 要求实现转盘转动抽奖的功能: 只有正确率大于等于 80% 才可以进行抽奖;“谢谢参与”概率为 90%,“恭喜中奖”概率为 10%; 需求实现 实…...
2024.1.23力扣每日一题——最长交替子数组
2024.1.23 题目来源我的题解方法一 枚举 题目来源 力扣每日一题;题序:2765 我的题解 方法一 枚举 每次都以两个相邻作为满足要求的循环数据,并且以一个布尔变量控制循环的位置 时间复杂度:O(n) 空间复杂度:O(1) pub…...
C语言王道练习题第七周两题
第一题 Description 输入一个学生的学号,姓名,性别,用结构体存储,通过 scanf 读取后,然后再 通过 printf 打印输出 Input 学号,姓名,性别,例如输入 101 xiongda m Output 输出…...
某马头条——day11+day12
实时计算和定时计算 流式计算 kafkaStream 入门案例 导入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusions><exclusion><artifactId>connect-json</artifactId&…...
springboot实现aop
目录 AOP(术语)引入依赖实现步骤测试验证感谢阅读 AOP(术语) 连接点 类里面哪些方法可以增强,这些点被称为连接点 切入点 实际被真正增强的方法 通知(增强) 实际增强的逻辑部分称为通知(增强) 通知(增强&…...
Golang 中高级工程师学习笔记
闭包的作用 闭包(Closure)是一种函数值,它可以引用在其外部定义的变量。闭包允许这些变量保持在函数内部,而不是被每次调用时重新创建。闭包的作用主要体现在以下几个方面 封装: 闭包允许函数访问其外部作用域中的变…...
USB-C接口给显示器带来怎样的变化?
随着科技的不断发展,Type-C接口已经成为现代电子设备中常见的接口标准。它不仅可以提供高速的数据传输,还可以实现快速充电和视频传输等功能。因此,使用Type-C接口的显示器方案也受到了广泛的关注。本文将介绍Type-C接口显示器的优势、应用场…...
写一份简单的产品说明书:格式和排版建议
现在的市场竞争那么激烈,拥有一份简洁明了的产品说明书可以说是很重要的。产品说明书不仅向用户提供了对产品的详细了解,还能够树立品牌形象,提升用户体验。 | 一、写一份简单的产品说明书—一些建议 1.创意封面设计 一个吸引人的封面设计能…...
【Python学习】Python学习21- 正则表达式(1)
目录 【Python学习】Python学习21- 正则表达式(1) 前言re.match函数实例 re.search方法re.match与re.search的区别参考 文章所属专区 Python学习 前言 本章节主要说明Python的正则表达式。 正则表达式是一个特殊的字符序列,它能帮助你方便的…...
Docker 和 Kubernetes:容器化时代的崛起与演变
在过去的十年间,容器化技术彻底改变了软件开发和部署的面貌。 Docker 的登场无疑是这场变革的催化剂,它将应用和服务的打包、分发、部署流程标准化,让开发者的生活变得更加简单。 紧随其后,Kubernetes 作为容器编排的领军者&#…...
美易官方京东养车回应索赔事件:推动行业健康发展并携手品牌商家加码补贴
近日,一则关于途虎养车起诉京东索赔500万元的新闻引起了业界的广泛关注。据华尔街见闻1月25日报道,针对此事,京东养车相关负责人作出了回应。京东养车表示,“震虎价”并非针对特定企业,其核心目的在于通过提升效率来改…...
深度学习与图像描述生成——看图说话(3)
目录 一、整体架构 二、学习策略 2.1 监督学习 2.2 无监督学习 2.3 强化学习 三、特征映射 3.1 定义 3.2 原理 3.3 关键技术 3.4 重要案例 3.5 特别注意下特征空间这一概念 四、语言模型 4.1 定义与原理 4.2 关键技术 4.3 重要性与作用 4.4 案例与应用 五、注…...
[SAP ABAP] ABAP编程中SY-SUBRC值的含义
在ABAP编程中,SY-SUBRC是一个系统变量,用于表示最近一次执行的系统命令(例如数据库操作、函数模块调用等)的结果状态码 SY-SUBRC的值用于检查命令是否执行成功,通常用于控制程序的流程 查询数据 使用SELECT语句选择查询 SY-SUBRC 0 &qu…...
测试模型分类
测试模型 1. 概述 软件测试和软件开发一样,都遵循软件工程原理,遵循管理学原理,所以理解好软件的开发模型会便于理解测试模型. 软件测试的一般流程: 我们发现一般的软件测试流程和软件开发的流程一样,但是这样的流程测试介入的较晚,对于前期重大的bug很难修复.所以测试的流程…...
mavros和PX4中的海拔高与椭球高转换
飞控高度传感器中一般有两种高度: 海拔高。也称AMSL(Above Mean Sea Level)height或者geoid height或者正高,顾名思义就是指高于当地平均海平面的高度。我猜气压计测得的高度应当就是与海平面相关的。椭球高。也称ellipsoid heig…...
洛谷刷题-【入门2】分支结构
目录 1.苹果和虫子 题目描述 输入格式 输出格式 输入输出样例 2.数的性质 题目描述 输入格式 输出格式 输入输出样例 3.闰年判断 题目描述 输入格式 输出格式 输入输出样例 4.apples 题目描述 输入格式 输出格式 输入输出样例 5.洛谷团队系统 题目描述 …...
文件包含技术总结
开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。 allow_url_fopen On(是否允许打开远程文件) allow_url_include On&…...
Docker搭建私有仓库
Docker搭建私有仓库 下载docker registry镜像 docker pull docker.io/registry2.registry镜像下载完成后,先创建一个存放镜像的目录。 mkdir -p /data/registry3.启动registry容器 docker run -itd -p 5000:5000 -v /data/registry:/var/lib/registry docker.io…...
【计算机网络】【练习题】【新加坡南洋理工大学】【Computer Control Network】
说明: 仅供学习使用。 一、题目描述 该题目描述一个网络中传播时延(Transmission Delay)的例子。题目如下: 二、问题解答(个人) 笔者第3问采用均值不等式求解。标答中采用求导数的方法求极值。似乎均值…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
