把C51代码编译成LIB库文件,头文件的宏定义不起作用了。
本帖最后由 neutronlmk 于 2022-3-10 15:34 编辑把C51代码编译成LIB库文件:
c51.h
c51.c
编译成c51.lib给项目调用。
其中c51.h有宏定义给c51.c使用,现在发现调用c51.lib之后,修改c51.h中的宏定义没有效果了。
请问生成c51.lib之后是不是宏定义无法再展开?
补充一下:
这问题的描述应该是“库中如何使用库外的宏定义?” 你这个问题真是愧对你这vip++的身份。编译的原理都没明白。 宏定义编译器进行预编译过程这个有关系么 shiva_shiva 发表于 2022-3-10 16:22
你这个问题真是愧对你这vip++的身份。编译的原理都没明白。
(引用自2楼)
v++非论坛授予{:titter:} {:titter:}
欢迎您假如 c51.h 中的宏定义,在编译出 c51.lib 时,已经被展开了,你后面再调整的话,需要重新在编译释放一次 c51.lib。 shiva_shiva 发表于 2022-3-10 16:22
你这个问题真是愧对你这vip++的身份。编译的原理都没明白。
(引用自2楼)
现在的 VIP++ 都是花钱买的,跟技能无关。 了解下编译连接过程,宏定义在编译时就替换和展开了,就是写死到库文件里了。头文件只是告诉使用者一些信息,比如函数原型等,再怎么改,也不会影响到库文件了。库文件虽然在使用者的项目里,但只参与连接过程。 shiva_shiva 发表于 2022-3-10 16:22
你这个问题真是愧对你这vip++的身份。编译的原理都没明白。
(引用自2楼)
身份是买的。
现在我晓得不能用了,有无方法、手段可以达到同样效果? vuo50z 发表于 2022-3-10 16:47
了解下编译连接过程,宏定义在编译时就替换和展开了,就是写死到库文件里了。头文件只是告诉使用者一些信息 ...
(引用自7楼)
我学到了,有无方法可以达到我要的效果?
比如一个红外解码程序,我定义#define IR_IO P0_0,我希望用户使用lib可库,并在头文件里面可以改成任意IO。 如果宏只是控制流程或者选项,那就用#ifdef,在C里写好各种情况的分支,如果宏作为参数,那最好还是以形参的方式传递,例如做接口函数,专门用来传递参数 neutronlmk 发表于 2022-3-10 16:54
我学到了,有无方法可以达到我要的效果?
比如一个红外解码程序,我定义#define IR_IO P0_0,我希望用户 ...
(引用自9楼)
全局变量,宏是编译时的,变量是运行时的。 neutronlmk 发表于 2022-3-10 16:54
我学到了,有无方法可以达到我要的效果?
比如一个红外解码程序,我定义#define IR_IO P0_0,我希望用户 ...
(引用自9楼)
可以用这个路思来试试,IO操作不要写死在库里,库外写一个IO读写函数,具体操作哪个IO,通过形参来给定,通过参数来传递你具体要操作哪个IO 本帖最后由 neutronlmk 于 2022-3-10 17:44 编辑
hjjnt2008 发表于 2022-3-10 16:56
如果宏只是控制流程或者选项,那就用#ifdef,在C里写好各种情况的分支,如果宏作为参数,那最好还是以形参的 ...
(引用自10楼)
用 #ifdef 不行,生成lib也只有生成时选择的唯一项。
IO口也不好作为参数传递
为难在这里 neutronlmk 发表于 2022-3-10 17:42
用 #ifdef 不行,生成lib也只有生成时选择的唯一项。
IO口也不好作为参数传递
为难在这里 ...
(引用自13楼)
动动脑筋,IO做参数传递还是有办法的 用变量传输了 neutronlmk 发表于 2022-3-10 17:42
用 #ifdef 不行,生成lib也只有生成时选择的唯一项。
IO口也不好作为参数传递
为难在这里 ...
(引用自13楼)
IO口控制预留回调函数,让用户自己实现。 Doding 发表于 2022-3-10 18:25
IO口控制预留回调函数,让用户自己实现。
(引用自16楼)
盼能最具体点 neutronlmk 发表于 2022-3-10 18:27
盼能最具体点
(引用自17楼)
需要操作IO时,把原来的IO0 = 1换成函数,把IO0和1作为参数传进去,用户实现这两参数怎么操作IO。 一般是把不怎么变动的代码或算法编译成lib吧?像楼主举的例子,是否应该把硬件相关剥离出来? 就算是不变动IO生成lib后跨硬件也不通用啊。如果是我我会这么做把红外解码做成lib,接口为IR_Decode(IR_GPIO_LEVEL)然后在.h文件里将IR_GPIO_LEVEL这个宏定义为IO的电平获取代码,#define IR_IO P0_0就是读P0_0了 结果只能是0或1被传入。想用哪个IO就 #define IR_IO PX_X 搞个操作io的回调函数,这样就能交互了 写个函数吧,在lib里调用这个函数就可以了。。。
laujc 发表于 2022-3-10 22:56
写个函数吧,在lib里调用这个函数就可以了。。。
(引用自21楼)
看来只有这个办法了 laujc 发表于 2022-3-10 22:56
写个函数吧,在lib里调用这个函数就可以了。。。
(引用自21楼)
读写io的操作可以写个函数给lib调用,曹亮有什么好建议?这个常量也偶尔需要修改的。常量的数量还很多,不适合用全局变量把他们传进去。 neutronlmk 发表于 2022-3-11 09:04
读写io的操作可以写个函数给lib调用,曹亮有什么好建议?这个常量也偶尔需要修改的。常量的数量还很多, ...
(引用自23楼)
你没明白本质,
我帮忙说细一点,最直接的面向接口编程:
将 lib 里面涉及到 IO 操作的,抽象封装为一套 IO 操作接口函数就好了,也就是对 IO 的操作,都是通过接口来访问操作。
到时候提供 lib 的同时,需要提供一套默认的 IO 操作接口函数的实现源码(如果改变了 IO 口,相应的调整这份源码的实现就好了)。 security 发表于 2022-3-11 09:19
你没明白本质,
我帮忙说细一点,最直接的面向接口编程:
(引用自24楼)
我有点点理解了。
我决定用一个c封装好读写IO的子程序,通过lib调用子程序要实现我的要求。
目前有另一个难题:众多的常量怎么传递进去?
回调函数,在LIB里面使用函数指针方式调用,LIB外把函数指针赋个具体的函数就行了 neutronlmk 发表于 2022-3-11 09:24
我有点点理解了。
我决定用一个c封装好读写IO的子程序,通过lib调用子程序要实现我的要求。
目前有另一个 ...
(引用自25楼)
需要修改的就不是常量了,不想用全局变量传递的话,照样用接口形式传递。 security 发表于 2022-3-11 09:37
需要修改的就不是常量了,不想用全局变量传递的话,照样用接口形式传递。 ...
(引用自27楼)
使用参数传递,参数就太多。
还是以红外解码为例,定时扫描红外信号引导码9ms,用50us扫描有一组上限下限,用100us扫描又是另一组上限下限。
如果在c文件使用宏定义,即使使用任意xxUS来扫描,编译器自动把上限下限自动运算出来,直接供程序使用。
编译成lib就不方便了。
总不能引导码,bit0,bit1的时序上限下限都做传进去。 neutronlmk 发表于 2022-3-11 09:50
使用参数传递,参数就太多。
还是以红外解码为例,定时扫描红外信号引导码9ms,用50us扫描有一组上限下限 ...
(引用自28楼)
参数整理一下做成结构体,直接结构体指针传进去,没必要使用宏定义 neutronlmk 发表于 2022-3-11 09:50
使用参数传递,参数就太多。
还是以红外解码为例,定时扫描红外信号引导码9ms,用50us扫描有一组上限下限 ...
(引用自28楼)
29 楼童鞋,是一种方法,另一种方法就是提供一个接口函数,例如:void GetXxxConfigs(uint8_t *xx0, uint8_t *xx1, uint8_t *xx2)
{
// 引导时间
*xx0 = ;
// 上限
*xx1 = ;
// 下限
*xx2 = ;
} 本帖最后由 neutronlmk 于 2022-3-11 10:43 编辑
security 发表于 2022-3-11 10:04
29 楼童鞋,是一种方法,另一种方法就是提供一个接口函数,例如:
(引用自30楼)
感谢,用接口函数方法直观些,代码可以实现封装到lib了。
我看看使用这个方法会增加多少rom。
——————
刚刚测试了,一个接口函数返回一个值,程序中直接使用,不增加开销。 security 发表于 2022-3-11 10:04
29 楼童鞋,是一种方法,另一种方法就是提供一个接口函数,例如:
(引用自30楼)
再请教:
宏定义:
#define CRC16_CCITT_POLY 0x1021
单独一个c文件:
uint16_t u16_GetCrc16Poly(uint16_t fu16_Poly)
{
return fu16_Poly;
}
lib中代码:
u16_CPoly = u16_GetCrc16Poly(CRC16_CCITT_POLY);
测试lib仍然没有把值传递进去,是哪里搞错了?
LIB:
uint16 mfu16_Poly;
void SetCrC16(uint16_t fu16_Poly)
{
mfu16_Poly=poly;
}
uint16 GetCrc16(void)
{
return mfu16_Poly*....;
} neutronlmk 发表于 2022-3-11 12:05
再请教:
宏定义:
(引用自32楼)
看 33 楼。
你那个 lib,又直接将接口函数的实参用宏来实现,编译的时候,宏已经被展开为常量了。 neutronlmk 发表于 2022-3-11 12:05
再请教:
宏定义:
(引用自32楼)
要理解编译时和运行时 初音之恋 发表于 2022-3-11 13:07
LIB:
uint16 mfu16_Poly;
void SetCrC16(uint16_t fu16_Poly)
(引用自33楼)
有点理解。这样写法,是不是使用前还得先调用一下接口函数,然后再调用算法的函数才完成一次使用?把程序给人调用还得教一教啊。
按你29楼的思路,是不是可以直接用一个单独的c文件,把这些宏定义的数据搞成一个全局常量数组,然后lib里面直接取数组来用? neutronlmk 发表于 2022-3-11 14:15
有点理解。这样写法,是不是使用前还得先调用一下接口函数,然后再调用算法的函数才完成一次使用?把程序 ...
(引用自36楼)
嗯比如
外部:
DevInfo mDevInfo;
void DeviceInit(void)
{
mDevInfo.data1=a;
mDevInfo.data2=b;
LIBDeviceInit(&mDevInfo);
LIB_Runing();
}
LIB:
typedef struct
{
int dabta1;
int data2;
}DevInfo,*pDevInfo;
pDevInfo mDevinfo_t;
void LIBDeviceInit(pDevInfo devinfo)
{
mDevinfo_t=devinfo;
}
void LIB_Runing(void);
...... 本帖最后由 neutronlmk 于 2022-3-11 16:28 编辑
初音之恋 发表于 2022-3-11 14:34
嗯比如
外部:
DevInfo mDevInfo;
(引用自37楼)
{:handshake:} {:handshake:} {:handshake:}
我用一个独立c,设一全局常量数组来存这些宏定义的数据,只增加一点rom的开销。
等下试一试。
——————
测试OK,就这样来封装我的程序了。 常量只能全局变量了。
页:
[1]