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,我还没去学习这块的细节,反正能用就行

e3f1ed83fb834fde8ee35059faf95a7e.png

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

e9e57bfe1ad04f1393eac89c494253f0.png

然后代码和C应用程序的差异的话就在函数声明或定义前加上

extern "C" _declspec(dllexport) int add_test(int x, int y);

不设置配置和平台的话,默认输出就在Debug路径下生成和项目名一样的DLL文件,如下图:

969a592af5c049aabc4abafe8e198d45.png

C#部分-使用动态链接库

        把编译生成的DLL文件放到C#编译输出的路径下,不配置的话就在如下路径:

ea1bae29460546589e5df985681b9f3e.png

在C#中调用C的话,核心代码就如下2行,

[DllImport("DLLTEST.dll",CallingConvention=CallingConvention.Cdecl)]
extern static int add_test(int x, int y);

还有需要注意的点,需要包含如下引用,当然写了如上第一行就会提示让包含了:

using System.Runtime.InteropServices;

感觉像是函数外部声明,能用就行,暂时没有去深究原理啥的,输出如下:

0e51a0b0e0bd4f75af5d6b424f0c7bf7.png

因为需要处理的数据通常比较多,所以就定义一个结构体,把需要传输的数据全放里面,然后用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);
  • 输出

f9732d18d81f40b8a7af00e1fa44496d.png

        今天下午在公司写了个维测工具,整个流程和上面测试步骤一致,能正常使用

Python部分-使用动态链接库

        把编译生成的DLL文件放到Python文件同级路径下,这样在Python代码中就直接使用DLL文件名即可,Python测试代码如下,调用数组那块先前在公司测试正常能用来自,忘了,懒得写了

import ctypes
dll = ctypes.windll.LoadLibrary('DLLTEST.dll')
print(dll.add_test(4, 5))

输出5:如下图:

0b803cd97e2a4c9ea73a8bd59f0e85b6.png

本来打算把整个工程打包放到CSDN来着,但免费的话审核不通过,所以就把C/C#部分代码都贴下面了:

C程序头文件

#pragma once
#ifndef DLL_TEST_H
#define DLL_TEST_H

typedef 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();
        }
    }
}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用xlwings库为Excel表格的单元格创建超链接----关于Python里xlwings库对Excel表格的操作(三十九)

这篇小笔记主要记录【如何使用xlwings库为Excel表格的单元格创建超链接】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库&#xff1b; &#xff08;2&…

雷盛红酒LEESON分享葡萄酒也有“社会责任感”?

葡萄酒文化从来都不仅仅是感官体验&#xff0c;一瓶佳酿的背后不但蕴含着风土人情、历史传承和文化交流&#xff0c;更反映了时代社会的变迁以及体现的社会责任意识。 目前葡萄酒生产商追求酒瓶越来越轻就是葡萄酒市场上的一个趋势&#xff0c;因为任何一个行业都在追求与世界共…

坦克大战游戏代码

坦克大战游戏 主函数战场面板开始界面坦克父类敌方坦克我方坦克子弹爆炸效果数据存盘及恢复图片 主函数 package cn.wenxiao.release9;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JFrame; import javax.swing.JMenu; impor…

套接字通信(附带单线程TCP套接字通信代码)

套接字-Socket 1. 概念 1.1 局域网和广域网 局域网&#xff08;LAN&#xff09;和广域网&#xff08;WAN&#xff09;是两种不同范围的计算机网络&#xff0c;它们用于连接多台计算机以实现数据共享和通信。 局域网&#xff08;LAN&#xff09;&#xff1a; 定义&#xff1…

【JavaEE】文件操作与IO

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

0121-1-计算机网络安全

计算机网络安全 1.Get 和 Post 的区别 结构&#xff1a;get 有请求体&#xff0c;post没有请求体 应用场景&#xff1a;get 用于获取数据&#xff0c;post用于提交数据&#xff1b; 缓存&#xff1a;get 的缓存保存在浏览器和web服务器日志中&#xff1b; 传输方式&#x…

typing python 类型标注学习笔记

在Python 3.5版本后引入的typing模块为Python的静态类型注解提供了支持。这个模块在增强代码可读性和维护性方面提供了帮助。 目录 简介为什么需要 Type hints typing常用类型typing初级语法typing基础语法默认参数及 Optional联合类型 (Union Type)类型别名 (Type Alias)子类型…

ESP32-HTTP_webServer库(Arduino)

ESP32-HTTP 介绍 ESP32是一款功能强大的微控制器&#xff0c;具有丰富的网络和通信功能。其中之一就是支持HTTP协议&#xff0c;这使得ESP32可以用于创建Web服务器。 HTTP是什么&#xff1f; HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;即超文本传…

[Error]连接iPhone调试时提示Failed to prepare the device for development.

环境&#xff1a; iPhone 7 Plus iOS 15.8 Xcode14.2 问题&#xff1a; 连接iPhone设备运行时&#xff0c;设备旁提示如下文案。 Failed to prepare the device for development. 这时强行点击运行按钮&#xff0c;会弹窗提示如下文案。 The run destination ZDMiPhone is n…

CTF show逆向5

1.查壳看看 没有壳&#xff0c;32位文件 同时注意到附件里的dll文件 2.放入IDA里看看 找到主函数 分别看看sub_4020B0 sub_4015BD 这两个函数 我发现一般看到MessageBoxA函数&#xff0c;都需要动态调试 动调看到 这里直接进行了返回,返回到了主函数 执行sub_4015BD函数 步…

力扣hot100 找到字符串中所有字母异位词 滑动窗口 双指针 一题双解

Problem: 438. 找到字符串中所有字母异位词 文章目录 思路滑动窗口 数组滑动窗口 双指针 思路 &#x1f469;‍&#x1f3eb; 参考题解 滑动窗口 数组 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( 1 ) O(1) O(1) class Solution { // 滑动窗口 …

【Gradle】Maven-Publishing

使用Java开发完成一个模块或者一个基础框架需要提供给团队项目使用&#xff0c;这个时候有两种方式可提供&#xff0c;一是提供源码&#xff0c;二是提供编译构建好的jar包供使用&#xff0c;这个时候需要讲构建好的包发布到公司的私服&#xff08;公司maven仓库&#xff09;&a…

分布式锁实现(mysql,以及redis)以及分布式的概念

道生一&#xff0c;一生二&#xff0c;二生三&#xff0c;三生万物 我旁边的一位老哥跟我说&#xff0c;你知道分布式是是用来干什么的嘛&#xff1f;一句话给我干懵了&#xff0c;我能隐含知道&#xff0c;大概是用来做分压处理的&#xff0c;并增加系统稳定性的。但是具体如…

C语言第四弹---printf和scanf详解

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 printf和scanf详解 1、printf和scanf详解介绍1.1 printf1.1.1 基本用法1.1.2 占位符1.1.3 占位符列举1.1.4 输出格式1.1.4.1 限定宽度1.1.4.2 总是显示正负号1.1…

第一篇【传奇开心果系列】WeUI开发原生微信小程序:汽车租赁小程序示例

传奇开心果博文系列目录 WeUI开发原生微信小程序示例系列博文目录博文目录一、项目目标二、编程思路三、初步实现汽车租赁微信小程序示例代码四、实现汽车租赁微信小程序的登录注册示例代码五、实现汽车租赁微信小程序的订单管理示例代码六、整合实现比较完整的汽车租赁微信小程…

css绘制下拉框头部三角(分实心/空心)

1:需求图: 手绘下拉框 带三角 2:网上查了一些例子,但都是实心的, 可参考,如图: (原链接: https://blog.csdn.net/qq_33463449/article/details/113375804) 3:简洁版的: a: 实心: <view class"angle"/>.angle{width:0;height:0;border-left: 10px solid t…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--机器人相关、强化学习

专属领域论文订阅 VX 扫吗关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航具身智能&#xff0c;机器人强化学习开放词汇&#xff0c;检测分割 [晓理紫…

K8s(七)四层代理Service

Service概述 Service在Kubernetes中提供了一种抽象的方式来公开应用程序的网络访问&#xff0c;并提供了负载均衡和服务发现等功能&#xff0c;使得应用程序在集群内外都能够可靠地进行访问。 每个Service都会自动关联一个对应的Endpoint。当创建一个Service时&#xff0c;Ku…

JS-日期对象

日期对象&#xff1a;用来表示时间的对象 作用&#xff1a;可以得到当前系统时间 实例化 在代码中发现了new关键字时&#xff0c;一般将这个操作称为实例化 创建一个时间对象并获取时间 1&#xff09;获得当前时间 const datenew Date() 2)获得指定时间 const datenew D…

Python项目——计算器(PySide6+Pyinstaller)

1、介绍 使用python编写一个计算器&#xff0c;可以实现基本的运算。【注】该项目最终还有一些细小的bug没有完善&#xff0c;例如符号可以一直输入。 2、实现 使用pyCharm创建一个新的项目。 2.1、设计UI 使用Qt designer设计一个UI界面&#xff0c;保存ui文件&#xff0…