C语言编译成DLL文件,给其他程序调用。C语言编译成EXE文件,执行简单功能。HEX文件合并

news/2024/11/29 3:55:23/

文章目录

  • 一、简介
  • 二、步骤
    • 1. 先编写c语言文件。用CRC8举例。crc8_2f.c crc8_2f.h
    • 2. 编译成DLL文件
    • 3. 给上位机调用
      • (1)C#
      • (2) 易语言
  • 三、编译成EXE
    • 1. 编写一个c文件。 merge_hex.c(例:hex文件合并)
    • 2. 编译文件
    • 3. 合并脚本.bat

一、简介

在联合开发过程中,用c语言写好功能函数,给其他上位机程序调用。

二、步骤

1. 先编写c语言文件。用CRC8举例。crc8_2f.c crc8_2f.h

#include <stdint.h>
#include <stdio.h>/* Constant array CRC8 */
static const uint8_t LIB_Crc8Table1[16] = {0x42u, 0x6du, 0x1cu, 0x33u, 0xfeu, 0xd1u, 0xa0u, 0x8fu,0x15u, 0x3au, 0x4bu, 0x64u, 0xa9u, 0x86u, 0xf7u, 0xd8u
};static const uint8_t LIB_Crc8Table2[16] = {0x42u, 0xecu, 0x31u, 0x9fu, 0xa4u, 0x0au, 0xd7u, 0x79u,0xa1u, 0x0fu, 0xd2u, 0x7cu, 0x47u, 0xe9u, 0x34u, 0x9au
};/*** @brief This function calculates a CRC8 over the data buffer* @param LIB_TempInputCrc8_cp[in]: pointer to the input data* @param LIB_TempLengthCrc8_u16[in]: Length of the input data* @return Calculated CRC8* @details Local variables*          Loop over all byte*              Execute CRC algorithm*          Return inverted result* @ReqKey MOD_LIB-64, MOD_LIB-65*/
uint8_t CRC8Calculation(const uint8_t* data, const uint16_t len) {/* Local Variables */uint8_t LIB_TempCrc8_u8 = 0xFFu;uint16_t LIB_TempIndexCrc8_u16;/* Loop over all bytes */for (LIB_TempIndexCrc8_u16 = 0u;LIB_TempIndexCrc8_u16 < len;LIB_TempIndexCrc8_u16++) {/* CRC Algorithm */LIB_TempCrc8_u8 = data[LIB_TempIndexCrc8_u16] ^ LIB_TempCrc8_u8;LIB_TempCrc8_u8 = (LIB_Crc8Table1[LIB_TempCrc8_u8 & 0x0Fu]) ^(LIB_Crc8Table2[LIB_TempCrc8_u8 >> 4u]);}return (LIB_TempCrc8_u8 ^ 0xFF);
}
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifndef CRC8_2F_H_
#define CRC8_2F_H_uint8_t CRC8Calculation(void* data, uint16_t size);
#endif

2. 编译成DLL文件

cmd 执行下面命令:

gcc -shared crc8_2f.c -o crc8_2f.dll

需要安装gcc编译器mingw32

3. 给上位机调用

(1)C#


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;namespace CallTheDll01
{class Program{// 在此处使用 crc8_2f.dll 文件的绝对路径[DllImport(@"D:\crc8_2f.dll",CallingConvention=CallingConvention.Cdecl)]public static extern byte CRC8Calculation(void* data, ushort size);// 上面已经使用了 crc8_2f.dll 文件的绝对路径,// 在此处可以只写该 dll文件名,但为了保险起见,还是最好写待调用dll文件的绝对路径名[DllImport("crc8_2f.dll", EntryPoint = "CRC8Calculation",CallingConvention =CallingConvention.Cdecl)]public static extern byte CRC8_Cal(void* data, ushort size);static void Main(string[] args){byte[] data = new byte[] {3, 32, 35, 6, 12, 21, 122};Console.WriteLine("{0}", CRC8Calculation(data, 7));Console.WriteLine("{0}", CRC8_Cal(data, 7));Console.ReadKey();}}

(2) 易语言

.版本 2.DLL命令 read, 整数型, "crc8_2f.dll", "@CRC8Calculation", 公开, @代表使用__stdcall,否则报错-堆栈错误.参数 buff, 字节集, 传址.参数 len, 整数型

三、编译成EXE

1. 编写一个c文件。 merge_hex.c(例:hex文件合并)

#include <direct.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>/*** @brief  得到文件行* @param  path: 文件路径* @retval 文件行数(hex文件每行44列)*/
int GetFileLIine(char* path) {int i = 0;//    char j = 0;char str[45];FILE* fp;//    printf("Path: %s \n",path);if ((fp = fopen(path, "r")) == NULL)printf("fail to open the file path:%s! \n", path);while (fgets(str, 45, fp)) {i++;}fclose(fp);return i;
}/*** @brief  路径处理* @param  ParaPath: * @param  TargetPath: 目标路径* @param  flag:  1表示遇到'\'需要进行增加一个'\'处理, 0表示不需要处理* @retval */
int FileNameHandle(char* ParaPath, char* TargetPath, int flag) {char* CurrentPath;int i = 0, j = 0, k = 0;int PathLevel = 0, PathLast = 0;// 获取传入的参数路径有多少个上级目录,也就是"..\"的个数for (i = 0; (ParaPath[i] == '\\') || (ParaPath[i] == '.'); i++) {if ((ParaPath[i] == '.') && (ParaPath[i - 1] == '.')) {PathLevel++;}}// printf("ParaPath:%s\n",ParaPath);// printf("PathLevel:%d  i is:%d\n",PathLevel,i);// 获取当前绝对路径if ((CurrentPath = getcwd(NULL, 0)) == NULL) {perror("getcwd error");}// printf("CurrentPath: %s\n",CurrentPath);// 当前绝对路径字符串由后往前遍历,根据上级目录个数PathLevel,去掉多余路径,得到参数路径的绝对路径for (i = strlen(CurrentPath) - 1; PathLast < PathLevel; i--) {if (CurrentPath[i] == '\\') {PathLast++;}}// printf("PathLast:%d  i is:%d\n",PathLast,i);// 将处理后的当前绝对路径,赋值到目标路径的前面for (j = 0, k = 0; j <= i; j++) {TargetPath[k++] = CurrentPath[j];if (flag)if (CurrentPath[j] == '\\')TargetPath[k++] = '\\';}TargetPath[k] = '\0';// printf("TargetPath:%s\n",TargetPath);for (i = 0; ParaPath[i] != '\0'; i++) {if (ParaPath[i] != '.') {TargetPath[k++] = ParaPath[i];if (flag)if (ParaPath[i] == '\\')TargetPath[k++] = ParaPath[i];}if ((ParaPath[i] == '.') && ((ParaPath[i - 1] != '.') && (ParaPath[i + 1] != '.')))TargetPath[k++] = ParaPath[i];}TargetPath[k] = '\0';// printf("TargetPath:%s\n",TargetPath);free(CurrentPath);return k;
}int FileHandle(char* path1, char* path2, char* path3, char* path4) {FILE* fp1;FILE* fp2;FILE* fp3;char str[45];char* mergeflie;int i = 0;int k1 = 0, k2 = 0;char CurrentPath[2048];FileNameHandle(path4, CurrentPath, 0);k1 = GetFileLIine(path1);k2 = GetFileLIine(path2);mergeflie = (char*)malloc((k1 + k2) * 45);mergeflie[0] = '\0';if ((fp1 = fopen(path1, "r")) == NULL)printf("fail to open the file path:%s! \n", path1);for (i = 0; i < k1 - 2; i++) {fgets(str, 45, fp1);strcat(mergeflie, str);}fclose(fp1);// printf("Path: %s,line number:%d \n",path1,i);if ((fp2 = fopen(path2, "r")) == NULL)printf("fail to open the file path:%s! \n", path2);// printf("k2-1:%d\n",k2-1);fgets(str, 45, fp2);for (i = 0; i < k2 - 1; i++) {fgets(str, 45, fp2);strcat(mergeflie, str);}fclose(fp2);i = strlen(mergeflie);mergeflie[i] = '\n';if ((fp3 = fopen(path3, "w")) == NULL)printf("fail to open the file path:%s! \n", path3);else {fwrite(mergeflie, strlen(mergeflie), 1, fp3);printf("creat %s success!\n", CurrentPath);  // 打印参数传入的原始路径}fclose(fp3);free(mergeflie);return 0;
}int main(int argc, char** argv) {char path[3][2048];if (argc < 4) {printf("error!\n");printf("参数缺失\n");return -1;}FileNameHandle(argv[1], path[0], 1);  // bootloader pathFileNameHandle(argv[2], path[1], 1);  // app pathFileNameHandle(argv[3], path[2], 1);  // mergeHex pathFileHandle(path[0], path[1], path[2], argv[3]);return 0;
}

2. 编译文件

gcc merge_hex.c -o mergeHEX2.exe

3. 合并脚本.bat

echo off
mergeHEX2.exe .\BOOT.hex .\MCU.hex .\boot_app.hex
pause

用于合并hex文件的小工具,通过批处理脚本调用传参,在MDK中,可以在魔术棒的User选项卡设置编译后调用批处理脚本,使用起来非常方便.


http://www.ppmy.cn/news/350422.html

相关文章

300字总结计算机flash,flash实训报告心得(共10篇).docx

flash实训报告心得(共10篇) 实训心得  一个星期的实训使我们对FLASH的学习有了更深入的了解&#xff0c;这次没有进行分组&#xff0c;所以难度加大了。经过几天的思考确定了自己要做的东西是什么&#xff0c;难度的加大对自己也是个锻炼的机会&#xff0c;自己要去发现问题&…

网页设计(一)

网页设计 提示&#xff1a;这里有基础内容&#xff0c;也有中级内容 例如&#xff1a;网页设计div布局 网页设计 网页设计前言一、什么是网页二、使用网页编辑软件&#xff08;一&#xff09;、初学者的网页制作软件&#xff08;二&#xff09;、中级网页制作软件&#xff08;…

HTML5+CSS期末大作业:篮球明星个人网站设计——篮球明星介绍(6页) 简单的学生DW网页设计作业成品 web课程设计网页规划与设计 简单个人网页设计作业 静态HTML旅行主题网页作业 DW

HTML5CSS期末大作业&#xff1a;篮球明星个人网站设计——篮球明星介绍(6页) 简单个人网页设计作业 静态HTML旅行主题网页作业 DW个人网站模板下载 大学生简单个人网页作品代码 常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、…

计算机专业毕业设计题目大全 (各类型系统设计大全)

计算机专业毕业设计题目大全 毕设论文答辩通关法则&#xff0c;看这一篇&#xff0c;源码都在下面了&#xff01;写在前面&#xff0c;尽管论文方法和毕设源码都有&#xff0c;但还是要看课自己敲完完善好。做好充分准备面对答辩。 1.网络留言薄 2.客户管理系统 3.多媒体积件管…

nand flash制备

1、晶圆wafer wafer 即为图片所示的晶圆&#xff0c;由纯硅&#xff08;Si&#xff09;构成。一般分为6英寸、8英寸、12英寸规格不等&#xff0c;晶片就是基于这个wafer上生产出来的。Wafer上的一个小块&#xff0c;就是一个晶片晶圆体&#xff0c;学名die&#xff0c;封装后就…

FLASH

最近一直在致力于基于ARM920T的FLASH的读写&#xff0c;虽然这部分一般没有多少人屑于研究&#xff0c;认为比较简单&#xff08;U-boot和VIVI中都有现成的支持程序&#xff09;&#xff0c;但对于初学的我&#xff0c;还是尽心尽力地学习一下&#xff0c;目的在于自己编写一个…

MCU前端设计简单记录

第一讲 Cortex-M3介绍及使用场景 一、Cortex-M3介绍 Cortex-M3内核是MCU的中央处理器单元, Cortex-M3内核通过接口总线的形式挂载了储存器、外设、中断等组成一个MCU&#xff1a; CM3的主要特点包括&#xff1a; • 性能强劲 • 功耗低 • 实时性好 • 代码密度高 • 使用…

tp6安装并使用rabbitMQ

最近因为业务需要,要用到MQ就去研究了一下,说实话,安装环境给我搞自闭了,大概是我太菜 刚开始使用yum换源,各种安装卸载始终找不到自己要用的版本,后来全部卸载,下载安装包 编译安装解百忧 我用的是erlang 25.3 的版本,MQ使用的是3.11.3的版本,符合官方要求,这里的版本是有强…