用gcc生成静态库和动态库
在linux系统下,实现一次动态库与静态库的生成与链接
创建一个test2文件夹,在其中完成本次操作
创建文件A1.c A2.c A.h test.c
编译文件A1.c A2.c
创建动态库libafile.a
生成可执行文件
执行结果
改写以前的代码,并采用静态库链接
在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。
改写的文件
生成静态库
ar crv libsub1a.a sub1.o
链接并执行
改写以前的代码,并采用动态库链接
将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。
编译文件
生成动态库
链接生成可执行文件并运行
maina 与mainso的对比
实例1使用库
文件的具体实现
1.代码
A1.c
#include<stdio.h>
void print1(int arg)
{
printf("A1 print arg:%d\n",arg);
}
A2.c
#include<stdio.h>
void print2(char *arg)
{
printf("A2 printf arg:%s\n",arg);
}
A.h
#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif
test.c
#include<stdio.h>
#include"A.h"
int main()
{
print1(1);
print2("test");
exit(0);
}
操作步骤
与在linux系统下,实现一次动态库与静态库的生成与链接如同。
Ubuntu、stm32下的程序内存分配问题
编写一个C程序,重温全局常量、全局变量、局部变量、静态变量、堆、栈等概念,在Ubuntu(x86)系统和STM32(Keil)中分别进行编程、验证(STM32 通过串口printf 信息到上位机串口助手) 。1)归纳出Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的分配地址,进行对比分析;2)加深对ARM Cortex-M/stm32F10x的存储器地址映射的理解。下图是一个Cortex-M4的存储器地址映射示意图(与Cortex-M3/stm32F10x基本相同,只存在微小差异)。
变量类型概述
全局常量(Global Constants)
全局常量是在整个程序中都可见的常量。它们在程序启动时被分配内存,并且其值在程序的整个生命周期中保持不变。
全局变量(Global Variables)
全局变量也是在整个程序中都可见的变量,但它们可以被修改。它们在程序启动时被分配内存,并且其生命周期与程序运行时间相同。
局部变量(Local Variables)
局部变量是在函数内部声明的变量,只在函数的作用域内可见。它们在函数调用时分配内存,并在函数返回时释放。
静态变量(Static Variables)
静态变量在程序的生命周期内保持其值,并且只在声明它们的函数内部可见。它们的内存分配在程序启动时完成。
堆(Heap)
堆是用于动态内存分配的区域,通常用于存储在程序运行时动态创建的数据。在C语言中,可以使用malloc和free函数来管理堆内存。
栈(Stack)
栈用于存储函数调用的上下文信息以及局部变量。栈是一种有限大小的数据结构,遵循先进先出的原则,通常由编译器进行管理。
在Ubuntu(x86)系统中的示例
在Ubuntu系统上,编写C程序可以使用标准的C编译器(如GCC)。以下是一个简单示例,演示了不同类型变量的分配地址:
#include <stdio.h>
// 全局常量
const int global_const = 10;
// 全局变量
int global_var = 20;
int main() {
// 局部变量
int local_var = 30;
// 静态变量
static int static_var = 40;
printf("Global Constant Address: %p\n", &global_const);
printf("Global Variable Address: %p\n", &global_var);
printf("Local Variable Address: %p\n", &local_var);
printf("Static Variable Address: %p\n", &static_var);
return 0;
}
在STM32(Keil)中的示例
在STM32上使用串口输出打印变量地址:
#include "stm32f10x.h"
#include <stdio.h>
// 全局变量
int global_var = 20;
int main() {
// 初始化串口
// ...
// 打印全局变量地址
printf("Global Variable Address: %p\n", &global_var);
while (1) {
// 主循环
}
}
在此示例中,使用printf
函数将全局变量的地址打印到串口终端上。
ARM Cortex-M存储器地址映射
对于ARM Cortex-M处理器(例如STM32F10x),存储器地址映射非常重要。不同的存储器区域用于不同的目的,包括程序代码、全局变量、堆、栈等。要深入理解存储器地址映射,您需要查阅特定型号的STM32数据手册和参考手册,以了解存储器区域的详细信息。
这些区域的地址范围通常包括Flash存储器(程序代码),RAM(全局变量、堆、栈等),外设寄存器等。存储器地址映射对于STM32的初始化和编程至关重要,因为它确定了如何分配和访问不同类型的数据。
变量类型概述
全局常量(Global Constants)
全局常量是在整个程序中都可见的常量。它们在程序启动时被分配内存,并且其值在程序的整个生命周期中保持不变。
全局变量(Global Variables)
全局变量也是在整个程序中都可见的变量,但它们可以被修改。它们在程序启动时被分配内存,并且其生命周期与程序运行时间相同。
局部变量(Local Variables)
局部变量是在函数内部声明的变量,只在函数的作用域内可见。它们在函数调用时分配内存,并在函数返回时释放。
静态变量(Static Variables)
静态变量在程序的生命周期内保持其值,并且只在声明它们的函数内部可见。它们的内存分配在程序启动时完成。
堆(Heap)
堆是用于动态内存分配的区域,通常用于存储在程序运行时动态创建的数据。在C语言中,可以使用malloc和free函数来管理堆内存。
栈(Stack)
栈用于存储函数调用的上下文信息以及局部变量。栈是一种有限大小的数据结构,遵循先进先出的原则,通常由编译器进行管理。
在Ubuntu系统中的示例
编写C程序,演示不同类型变量的分配地址:
#include <stdio.h>
// 全局常量
const int global_const = 10;
// 全局变量
int global_var = 20;
int main() {
// 局部变量
int local_var = 30;
// 静态变量
static int static_var = 40;
printf("Global Constant Address: %p\n", &global_const);
printf("Global Variable Address: %p\n", &global_var);
printf("Local Variable Address: %p\n", &local_var);
printf("Static Variable Address: %p\n", &static_var);
return 0;
}
在Keil中的示例
在STM32上使用串口输出打印变量地址:
#include "stm32f10x.h"
#include <stdio.h>
// 全局变量
int global_var = 20;
int main() {
// 初始化串口
// ...
// 打印全局变量地址
printf("Global Variable Address: %p\n", &global_var);
while (1) {
// 主循环
}
}
ARM Cortex-M存储器地址映射
对于ARM Cortex-M处理器(例如STM32F10x),存储器地址映射非常重要。不同的存储器区域用于不同的目的,包括程序代码、全局变量、堆、栈等。。
这些区域的地址范围通常包括Flash存储器(程序代码),RAM(全局变量、堆、栈等),外设寄存器等。