C语言 python 全局变量定义重定义

19:50 提问
C++API函数的重定义。编译无法通过的问题。
在一个生成dll的C++工程,头文件Local.h中,有如下代码:
DLL IMPORT WORD WINAPI PrintScreen(HWND,WORD,WORD,WORD,LPSTR,BOOL)
在c文件中也是调用的这个6各参数的函数。但是编译的时候,由于在系统API:winuser.h中,有一个3各参数的同名函数,PrintScreen,导致编译提示重定义。无法编译通过。
我想问一下,在本地中定义的这种跟系统api同名的函数,算是对系统函数的重写吗?调用的时候是怎么样的?我如何才能编译通过?
另:VS6.0同样的情况不会报错,VS2012就会报错。应该如何处理?
按赞数排序
不要跟系统取同样的名称,不然容易冲突,也会出现莫名其妙的错误。
最好是取自己的名字,然后加名字空间来区分。
没办法重写API中的函数,如果你非要用一样的名字,可以用namespace区分
换名称,前边加些前缀,比如myPrintScreen,更复杂点就用namespace
C++重写概念是针对类的机制,重写的条件之一有:继承关系
Win32 API函数不支持重写
lihao_ningxia
我的方法和lihao_ningxia
一样 在使用自定义的函数是加上其他的比如Myxxxxx或者返回类型 Vd_xxxxx It_xxxxx
1.换名称。
2.把函数放到类里面。
3.用命名空间(namespace).
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐查看: 2007|回复: 4
单独编译没错,知道是重定义,不知怎么改 求指导 谢谢
主题帖子精华
初级会员, 积分 182, 距离下一级还需 18 积分
在线时间0 小时
Rebuild target 'stm32-demo'
compiling misc.c...
compiling stm32f10x_adc.c...
compiling stm32f10x_bkp.c...
compiling stm32f10x_can.c...
compiling stm32f10x_cec.c...
compiling stm32f10x_crc.c...
compiling stm32f10x_dac.c...
compiling stm32f10x_dbgmcu.c...
compiling stm32f10x_dma.c...
compiling stm32f10x_exti.c...
compiling stm32f10x_flash.c...
compiling stm32f10x_fsmc.c...
compiling stm32f10x_gpio.c...
compiling stm32f10x_i2c.c...
compiling stm32f10x_iwdg.c...
compiling stm32f10x_pwr.c...
compiling stm32f10x_rcc.c...
compiling stm32f10x_rtc.c...
compiling stm32f10x_sdio.c...
compiling stm32f10x_spi.c...
compiling stm32f10x_tim.c...
compiling stm32f10x_usart.c...
compiling stm32f10x_wwdg.c...
compiling main.c...
main.c(15): warning: &#223-D: function "uart_init" declared implicitly
& & &uart_init(9600); & & & & & &//串口初始化为9600
main.c(18): warning: &#223-D: function "delay_Init" declared implicitly
& & delay_Init(); & & & &&
main.c(19): warning: &#223-D: function "sys_init" declared implicitly
& & sys_init();&
main.c: 3 warnings, 0 errors
compiling stm32f10x_it.c...
compiling delay.c...
compiling sys.c...
compiling rs485.c...
compiling modbus.c...
compiling usart3.c...
compiling i2c.c...
compiling system_stm32f10x.c...
compiling core_cm3.c...
assembling startup_stm32f10x_hd.s...
linking...
..\OUTPUT\demo.axf: Error: L6200E: Symbol __stdout multiply defined (by modbus.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol __stdout multiply defined (by usart3.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol _sys_exit multiply defined (by modbus.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol _sys_exit multiply defined (by usart3.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol fputc multiply defined (by modbus.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol fputc multiply defined (by usart3.o and main.o).
..\OUTPUT\demo.axf: Error: L6200E: Symbol SystemInit multiply defined (by system_stm32f10x.o and sys.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 7 error messages.
"..\OUTPUT\demo.axf" - 7 Error(s), 3 Warning(s).
Target not created
我是昨晚刚解决的,想法分享&的&后来想&都是玩32的&大部分不会遇到就没有发。。。。我也是在一个人的博客上找到的。。。。
全局变量相关
全局变量是指在整个项目工程中可见。
首先要理解&&&定义和声明
&&&&变量定义使用“数据类型+变量名称”的形式,编译器需要给他分配内存单元的;
变量声明使用“extern&变量类型+变量名称”的形式,是告诉编译器我这个变量将在其 ...
主题帖子精华
中级会员, 积分 367, 距离下一级还需 133 积分
在线时间0 小时
我是昨晚刚解决的,想法分享&的&后来想&都是玩32的&大部分不会遇到就没有发。。。。我也是在一个人的博客上找到的。。。。
全局变量相关
全局变量是指在整个项目工程中可见。
首先要理解&&&定义和声明
&&&&变量定义使用“数据类型+变量名称”的形式,编译器需要给他分配内存单元的;
变量声明使用“extern&变量类型+变量名称”的形式,是告诉编译器我这个变量将在其他外部c文件中定义,我这里只是在外部用它,不需要分配内存单元。
这样编译器就不给他分配内存空间,而等到真正遇到变量定义的时候再给他分配内存空间。
&这样说&大家应该了解了吧,这样举个例子
用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用。
Key变量我需要在main.c和qq.c中使用,最开始我的想法是在qq.h中定义了,然后在main.c中用include包含就行了,连接正确,可是编译出问题了,错误是重复定义了,找了好久毛病没弄懂,后来在一个博客里发现的&&#include命令就是原封不同的把头文件中的内容搬到#include的位置,所以相当于main.c和qq.c中都执行了一次unsigned&char&key,
而C语言中全局变量是项目内(或者叫工程内)可见的,这样就造成了一个项目中两个变量key,编译器就认为是重复定义。
此刻参考我上面说的定义和声明?有思路没?
就是在一个.c文件里定义char&key,在另一个.c文件里用extern声明
&下面来说说结构体是如何定义的
不同于普通类型,如果不预先通知编译器,编译器是不会识别你自定义的类型的。这个时候,*.h文件便出现了。不是定义结构类型不占内存吗?那好,我大结构体的定义放在*.h文件中,这样一来,无论你incude无数次,内存都不会被占用的。而且这样还有个好处,在别的文件中可以include这个*.h文件,这样,在这个文件中,编译器就可以识别你的自定义类型了,目的不就达到了???假如我在global.h中定义了
typedef&struct&_POSITION
{
????????int&x;
????????int&y;
}POSITION;
那么我可以在一个global.c文件中实现全局变量的定义,不过要include那个*.h文件,比如
/*&***global.c&*******&*/?
include&“global.h”
POSITION&current,;??
这样就定义了cunrrent这个变量,在别的文件中引用这个变量时,只要extern&nbspOSITION&current;进行声明,然后就可以用了,不过这个文件也还得include&"global.h"&因为如果不包含,在这个文件中是不识别POSITION类型的。
再不玩命努力,你就老了
主题帖子精华
初级会员, 积分 182, 距离下一级还需 18 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
没事&&谢了
主题帖子精华
金钱124777
在线时间1050 小时
这个问题貌似不好解决。以前遇到过,但是忘记解决办法了。。。
所以,帮不到你。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 182, 距离下一级还需 18 积分
在线时间0 小时
回复【3楼】逍遥居士_888:
---------------------------------
多谢
Powered by问题是这么开始的:
最近在看一个PHP的扩展源码,编译的时候的遇到一个问题:
ld: 1 duplicate symbol for architecture x86_64
仔细看了一下源码,发现在头文件中 出现了全局变量的定义。
简化一下后,可以这么理解:
#ifndef T1_H
#define T1_H
int a = 0;
//------------------
#include "t1.h"
#include "t2.h"
int main(){
//-----------------
#include "t1.h"
//----------------
#include "t2.h"
这两个c文件能否通过编译?想必有点经验的必会说 不会,重定义了。
那么是否真的如此?并不这么简单。
第一个问题,#ifndef 的这个宏是否防止了重定义(redefinition)?
答案:是。但是是在单个translation unit中(wiki&)。
#ifndef 的头文件宏称为&include guards的()
我们知道,一个完整的编译的过程是经过&
one.c& --&& PREPROCESSOR -&&&&tmp.c(temporary)&& -&& COMPILER& -&&&one.obj&& -& LINKER -&&&one.exe&
这三个过程的,而在预编译阶段,便会把include的文件展开,我们使用cc -E 命令来查看t1.c的预编译的结果:
cc -E t1.c
# 1 "t1.c"
# 1 "&built-in&" 1
# 1 "&built-in&" 3
# 321 "&built-in&" 3
# 1 "&command line&" 1
# 1 "&built-in&" 2
# 1 "t1.c" 2
# 1 "./t1.h" 1
int a = 0;
# 3 "t1.c" 2
# 1 "./t2.h" 1
# 4 "t1.c" 2
int main(void){
看到编译器把 t1.h 做了展开,我们看到了 a的定义。
而在t2.c 的预编译结果里,我们同样看到了a的展开定义:
cc -E t2.c
# 1 "t2.c"
# 1 "&built-in&" 1
# 1 "&built-in&" 3
# 321 "&built-in&" 3
# 1 "&command line&" 1
# 1 "&built-in&" 2
# 1 "t2.c" 2
# 1 "./t2.h" 1
# 1 "./t1.h" 1
int a = 0;
# 2 "./t2.h" 2
# 2 "t2.c" 2
所以到了Link阶段,编译器会看见两个a的定义。原因在于 include guards 只在同一个translation unit(一个c文件和include的文件的编译过程)内起作用,两个编译单元是编译过程是分开的,所以无法察觉到另外一个里面的#ifdefine内容,可以这么理解:
t1.c -& t1.s -& t2.o
*-& - t.otu
t2.c -& t2.s -& t2.o
所以,在头文件中是不应该define 变量,只应该declare。&
include guards 是为了防止两个文件相互引用而造成的循环引用问题。读者可以试试去除include guards,看看效果。
以上的解答也同时解释了 为什么 include guards 没有在这个例子下起到防止重定义的作用。
那么,如何强制在头文件中定义全局变量呢?
正确的做法是头文件declare,c文件define,老生常谈的问题,不再赘述。这里提供两个技巧:对于函数,给出这么个办法,添加inline或者static 关键字。
或者有人直接这么搞:
#ifdef DEFINE_GLOBALS
#define EXTERN
#define EXTERN extern
EXTERN int global1;
EXTERN int global2;
那么在头文件中定义全局变量真的一定是错误的吗?
答案是不一定。
如果我们写这样一个c文件:
int main(void){
你肯定认为是重定义了,不过你可以试试 cc ,并不会报错,甚至没有warning。
原因其实在于 tentative defination,里的相关定义是
A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.
意义是,如果declare了一个变量,但是没有初始化,在同一个translation unit结束后,还没有发现初始化,那么应该把这个变量赋值为0。所以,如果依据C99的规则,你在头文件中写入
仍然会被编译为int a = 0。所以多次包含,仍然会重定义报错。
而gcc vc并没有完全遵循这个标准,C99中最后面还有一段:
Multiple external definitions&
There may be more than one external definition for the identifier of an object, with or&without the explicit use o if the definitions disagree, or more than&one is initialized, the behavior is undefined (6.9.2).
多么尴尬的一段话,我们可以理解为gcc 和 vc允许在整个程序编译过程中的&tentative definition&,而非单一个"translation unit"内。
那么我们便可以理解之前两个int a的不会报错的场景了。gcc vc 视这样的没有初始化的变量为extern而非define。
同样可以理解的是,如果我们添加了初始化值:
int a = 0;
int a = 0;
int main(void){
则会报错了:
t1.cpp:5:5: error: redefinition of 'a'
./t1.h:4:5: note: previous definition is here
t1.cpp:6:5: error: redefinition of 'a'
./t1.h:4:5: note: previous definition is here
2 errors generated.
结合tentative definition的定义,便不难理解了。
到这里,细心的读者可能发现,我们这里的tentative definition只局限于C语言,是的。C++并不认可这一概念,把所有的 视为变量定义。所以,如果使用c++,这些又会全部变成 redefinition 或者 duplicate symbol了。
吐槽:一个看似简单的问题,查阅了一天的资料,引申出这么多概念,才彻底弄明白,我真的学过C嘛( ⊙ o ⊙ )?
阅读(...) 评论()C语言类型重定义错误_百度知道
C语言类型重定义错误
我用VC++2010编一个C语言工程。工程的每个文件中都需要用到一个结构类型。于是我在自定义的头文件中定义了一个结构变量struct player{……};。并且在主文件中定义了该结构类型的三个全局变量struct player player1, player2, player3,在其他文件中引用这三个...
我有更好的答案
可以这么解决,把你的头文件这么改:#ifndef
XXX##define XXx在这里粘贴你原来头文件的内容#endif
采纳率:35%
documents.h可能被包含了多次吧 ?
每个文件中包含一次。一共有三个C文件main.c; game.c; player.c,然后就是一个头文件documents.h。这样有问题吗?
可否发给我看一下呢
邮箱可以告诉我吗?
本回答被提问者采纳
在头文件处添加:#ifndef
XXX##define XXx添加你想包含的头文件#endif
为您推荐:
其他类似问题
c语言的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。关于变量重定义的问题
[问题点数:30分,结帖人guoxiaohua57]
关于变量重定义的问题
[问题点数:30分,结帖人guoxiaohua57]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年11月 挨踢职涯大版内专家分月排行榜第二2011年9月 Linux/Unix社区大版内专家分月排行榜第二
2012年1月 Linux/Unix社区大版内专家分月排行榜第三2011年8月 C/C++大版内专家分月排行榜第三2011年8月 Linux/Unix社区大版内专家分月排行榜第三2010年4月 C/C++大版内专家分月排行榜第三
2012年11月 挨踢职涯大版内专家分月排行榜第二2011年9月 Linux/Unix社区大版内专家分月排行榜第二
2012年1月 Linux/Unix社区大版内专家分月排行榜第三2011年8月 C/C++大版内专家分月排行榜第三2011年8月 Linux/Unix社区大版内专家分月排行榜第三2010年4月 C/C++大版内专家分月排行榜第三
2009年5月 C/C++大版内专家分月排行榜第三
匿名用户不能发表回复!|

我要回帖

更多关于 python 定义变量 的文章

 

随机推荐