交叉编译时传入宏参数
㈠ 能在linux下,使用#pragma来定义宏吗
对于字节对齐的设置, 好像没有一个标准, 各个编译器都有自己的方法, #pragma pack(1) 应该是 VC 上的吧! 至于 arm-linux-gcc 没用过, 不过用过非 arm 的嵌入式 gcc, 有一个命令行选项, 好像是 -fpack-struct, 可以以紧凑方式生成结构数据. 你搜索一下这个选项, 应该有很多说明的.
PS: 在一些嵌入式的CPU下, 会有一种对齐异常, 你在使用这个选择的时候应该注意一下.
㈡ 请问C语言中带参数的宏和函数的比较
宏是用于编译器处理的,他在程序编译时,会在对应位置展开成代码。。,这就相当于你在告诉编译器,我想在这个位置加一些代码,代码的内容已在宏中定义,请编译器自己支找。。。,也就是说程序在运行时,早已变成了对应位置上的代码,此时已没有宏的概念了。。。。
而函数则是运行时,调用。他不会在编译时,在对应位置上加上函数代码,只是加上一个函数入口指针。。。从这个入口去运行一段代码。。。运行完了之后回到当前位置继续执行。。。。
可以简单的认为,宏是在编译时上起作用,而函数是运行时起作用。。。
㈢ 编译器有没有宏定义32位和64位
请问是什么语言的编译器?
如果是C,应该无法宏定义。C关于具体平台的实现很多依赖于具体系统的std库,而编译器的位数也是在安装时就决定的,无法动态修改
但可以交叉编译,具体过程有点复杂,这里就不提了
㈣ C语言中的宏定义如何传递形参
给宏传递运行时计算的变量是绝无可能办到的。
不过假如只是这一个循环的话,可以利用预处理展开……
#defineREPEAT_0(f)f(0)
#defineREPEAT_1(f)REPEAT_0(f)f(1)
#defineREPEAT_2(f)REPEAT_1(f)f(2)
#defineREPEAT_3(f)REPEAT_2(f)f(3)
#defineREPEAT_4(f)REPEAT_3(f)f(4)
#defineREPEAT_5(f)REPEAT_4(f)f(5)
#defineREPEAT_6(f)REPEAT_5(f)f(6)
#defineREPEAT_7(f)REPEAT_6(f)f(7)
#defineREPEAT_8(f)ERROR_EXCEED_LIMIT
#defineREPEAT(n,f)REPEAT_##n(f)
/*用法如下*/
#defineLD(n)LEFT_BACK(n);Delay(4);
REPEAT(7,LD)
好处是这个宏是可以重用的,在别的地方也可以使用,并且不占运行时间。
㈤ 急(C语言)比较带参的宏与带参的函数之间的区别
区别:
1、宏会在编译器在对源代码进行编译的时候进行简单替换,不会进行任何逻辑检测,即简单代码复制而已。
2、宏进行定义时不会考虑参数的类型。
3、参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小。
4、参数宏的运行速度会比函数快,因为不需要参数压栈/出栈操作。
5、参数宏在定义时要多加小心,多加括号。
6、函数只在目标文件中存在一处,比较节省程序空间。
7、函数的调用会牵扯到参数的传递,压栈/出栈操作,速度相对较慢。
8、函数的参数存在传值和传地址(指针)的问题,参数宏不存在。
㈥ C语言 有参数宏定义
宏属于预编译,在编译的时候就将你的
SSSV(sa,sb,sc,vv);
替换成
sa=l*w;sb=l*h;sc=w*h;vv=w*l*h;
这些编译器已经给你处理了,宏这个就是直接替换
宏有编写规范的,你这里写的宏并不规范,建议上网查一下宏书写的规范
㈦ C语言函数问题。带参数的宏ab这里是实参,下面mn也是实参,所以这里是下面的实参传给上面的实参吗
普通函数的声明,定义里用的叫形参,普通函数调用时,调用语句里的参数叫实参。
宏与它们不一样,宏在预编译期间,做的工作 是 替代 (字符替代,名字替代)。
#defind area(a,b) (PI * a * b) 里面的 PI 要被 前面PI 的 宏定义 替代成:
#defind area(a,b) ((asin(1) * 2) * a * b)
然后程序里的 s = area(m,n); 要用 area(a,b) 的 宏 替代,同时要把 实际参数 m,n代入,变成:
s = ((asin(1) * 2) * m * n);
上述工作完成后,编译器,再把 这个替代工作完成后的 源程序, 编译和链接成 可执行程序 .exe 文件。
㈧ C/C++宏定义可不可以传入参数
#define P(a,b,c,d,e,f,g.........)参数可以随便设,宏定义其实是一个预处理替换,只是你要将对应的参数执行正确的操作。在C++中宏定义一系列简单操作的话可以用inline函数来替换,编译器对inline函数的处理是把接受了参数的inline函数的函数体和目标代码进行替换,有点像宏但比宏安全。
例如:#define P(x,y) int array[x]; cout << array[y];
在main中书写P(3,2)则编译器便把P(3,2)替换为 int array[3]; cout << array[2];
也可以使用inline函数如:
inline void func(const int& x,const int& y){
int array[x];
cout << array[y];
}
但有时候使用宏定义却很危险如:
#define P(x,y) (x) > (y) ? (x):(y)
int a = 3;
int b;
对于这样的语句b = P(++a,3)最后b却等于5,这并不是你想要的结果,这个时候使用inline函数就可以解决宏定义的不安全问题如:
template<class T>
inline const T& func(const T& x,const T& y){
return x > y ? x : y;
}
这样b = (++a,3)最后的结果便是4。
㈨ 如何在configure时,将编译参数传入,改变默认的编译器gcc成arm
你是要交叉编译吧,这个不是改参数就能做到的,而是需要另外的交叉编译工具。是想在Linux下编译出能在手机上运行的二进制文件么,网络吧,不是三言两语能讲明白的。
㈩ Qt交叉编译遇到的问题
QT相关的安装软件包:
(1) tmake-1.13.tar.gz (编译工具,如progen与tmake)
(2) qt-embedded-2.3.7.tar.gz (提供了qte的库)
(3) qt-x11-2.3.2.tar.gz (为了生成相应的QT工具,如designer和qvfb等)
(4) qtopia-free-1.7.0.tar.gz (QTE的桌面环境程序)
(5) cross-3.3.2.tar.bz2 (交叉编译工具)
一、安装工具
1 安装 tmake
在 Linux 命令模式下运行以下命令:
tar xfz tmake-1.11.tar.gz
export TMAKEDIR=$PWD/tmake-1.11
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
export PATH=$TMAKEDIR/bin:$PATH
2 安装 Qt/Embedded 2.3.7
在 Linux 命令模式下运行以下命令:
tar xfz qt-embedded-2.3.7.tar.gz
cd qt-2.3.7
export QTDIR=$PWD
export QTEDIR=$QTDIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure –qconfig local–qvfb -depths 4,8,16,32
make sub-src
cd ..
上述命令 ./configure -qconfig -qvfb -depths 4,8,16,32 指定 Qt 嵌入式开发包生成虚拟缓冲帧工具qvfb,并支持 4,8,16,32 位的显示颜色深度。另外我们也可以在 configure 的参数中添加-system-jpeg 和 gif,使 Qt/Embedded 平台能支持 jpeg、gif 格式的图形。
上述命令 make sub-src 指定按精简方式编译开发包,也就是说有些 Qt 类未被编译。Qt 嵌入式开发包有 5种编译范围的选项,使用这些选项,可控制 Qt 生成的库文件的大小,但是您的应用所使用到的一些 Qt 类将可能因此在 Qt 的库中找不到链接。编译选项的具体用法可运行./configure -help 命令查看。
在这一过程的configure中出现了问题:有一个变量没有声明,发现是少了一个头文件,加上即可,make顺利通过,看到了enjoy!
3 安装 Qt/X11 2.3.2
在 Linux 命令模式下运行以下命令:
tar xfz qt-x11-2.3.2.tar.gz
cd qt-2.3.2
export QTDIR=$PWD
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure -no-opengl
make
make -C tools/qvfb
mv tools/qvfb/qvfb bin
cp bin/uic $QTEDIR/bin
cd ..
根据开发者本身的开发环境,也可以在 configure 的参数中添加别的参数, 比如-no-opengl 或-no-xfs,可以键入./configure -help 来获得一些帮助信息。
在这个安装过程中也出现了很多错误,典型的就是在make过程中:
/usr/local/qt-2.3.2/include/qvaluestack.h:57: error: cannot convert 'QValueListIterator<QMap<QString, QString> >' to 'const char*' for argument '1' to 'int remove(const char*)'
/usr/local/qt-2.3.2/include/qvaluestack.h: In member function 'T QValueStack<T>::pop() [with T = QString]':
xml/qxml.cpp:2502: instantiated from here
/usr/local/qt-2.3.2/include/qvaluestack.h:57: error: cannot convert 'QValueListIterator<QString>' to 'const char*' for argument '1' to 'int remove(const char*)'
make[2]: *** [xml/qxml.o] Error 1
make[2]: Leaving directory `/usr/local/qt-2.3.2/src'
make[1]: *** [sub-src] Error 2
make[1]: Leaving directory `/usr/local/qt-2.3.2'
make: *** [init] Error 2
这个错误是说,在文件qvaluestack.h的57行出错。改正方法是修改文件qt-2.3.2/ include/qvaluestack.h的 第57行,将remove( this->fromLast() );改为 this->remove( this->fromLast() );
修改时可能要更改文件权限,变成可写的,chmod 666 qvaluestack.h。然后make顺利通过,看到了enjoy。
二、交叉编译 Qt/Embedded 的库
开发居于 Qt/Embedded 的应用程序要使用到 Qt/Embedded 的库,编写的 Qt 嵌入式应用程序最终是在YLE270开发板上运行的,因此在把 Qt 嵌入式应用程序编译成支持 YLE270 的目标代码之前,需要两样东西,一个是 arm9 的 linux 编译器,另一个是经 arm9 的linux 编译器编译过的 Qt/Embedded 的库。安装交叉编译工具 cross-3.3.2 前面已经安装过了。
这一步主要是配置 Qt/Embedded2.3.7 的安装,Qt/Embedded 的安装选项有很多个,您可以在命令行下直接输入“./configure”来运行配置,这时安装程序会一步一步提示你输入安装选项。您也可以在“./configure”后输入多个安装选项直接完成安装的配置。在这些选项中有一个选项决定了编译 Qt/Embedded 库的范围,即可以指定以最小,小,中,大,完全 5 种方式编译 Qt/Embedded 库。另外 Qt/Embedded 的安装选项还允许我们自己定制一个配置文件,来有选择的编译 Qt/Embedded 库,这个安装选项是“-qconfig local” ;当我们指定这个选项时,Qt/Embedded库在安装过程中会寻找qt-2.3.7/src/tools/qconfig-local.h 这个文件,如找到这个文件,就会以该文件里面定义的宏,来编译链接 Qt/Embedded 库。
具体过程如下:
cd qt-2.3.7
export QTDIR=$PWD
export QTEDIR=$QTDIR
make clean
./configure –xplatform linux-arm-g++ -shared –debug (接下行)
-qconfig local -qvfb -depths 4,8,16,32
make
cd ..
在make中出现了错误,有变量没有声明,原来是优龙公司为了避免初学者在一开始就直接接触到 Qt/Embedde 的复杂的宏编译选项,把这些宏定义到一个名为 qconfig-local.h的安装配置文件中,在安装 Qt/Embedded 的时候,需要把这个文件复制到 Qt/Embedded 的安装路径的/src/tools 子路径下,
cp /配置文件所在路径/qconfig-local.h ./src/tools
make顺利通过,看到了enjoy。
最后就可以在命令行下输入make 命令对整个工程进行编译链接了,在这里,要把过程中产生的文件放在同一个文件夹里面,方便应用。
在最后make完毕以后我还是遇到了一个问题,就是生成的可执行文件不能运行,运行时提示:./hello cannot execute binary file,当然不能直接在自己的主机上运行了,因为生成的二进制文件要下到板子上运行的。接上液晶屏,板子上电,把生成的可执行文件下载到板子上,要chmod一下,不然权限不够,终于在液晶屏上看到了自己弄的小程序,好开心!
三、添加一个 Qt/Embedded 应用到 QPE
以hello,world!为例
1 在工作的机器上解包 qtopia
tar zxvf qtopia-free-1.7.x.tar.gz
cd qtopia-free-1.7.x
export QTDIR=$QTEDIR
export QPEDIR=$PWD
export PATH=$QPEDIR/bin:$PATH
注意在上面已经设定环境变量 QPEDIR 为 QPE 的安装(解包)路径。
2 建立 Hello,World 的例子程序的图标文件
方法是:制作一个 32 X 32 大小的 PNG 格式的图标文件,将该文件存放在$QPEDIR/pics/inline 目录下,然后使用以下命令将$QPEDIR/pics/inline 目录下的所有图形文件转换成为一个 c 语言的头文件,这个头文件包含了该目录下的图形文件的 rgb 信息。
qembed --images $QPEDIR/pics/inline/*.*
> $QPEDIR/src/libraries/qtopia/inlinepics_p.h
3 交叉编译 qtopia
在$QPEDIR 路径下,运行以下命令
cd src
./configure –platform linux-arm-g++
make
cd ..
在这一过程中也出现了比较大的错误,在make的时候又出现了error,是resource.cpp的174行的变量qembed_findImage没有声明,考虑到以前遇到的情况,推断可能是少了某个头文件,但是又不知道是哪一个,google了很久都没有找到解决办法,没办法只好点开src/libraries/qtopia下面的每一个头文件看了一遍,还是没有发现有含有这个变量的文件,继续google,然后发现了inlinepics_p.h中包含qembed_findImage,于是vi /usr/local/qtopia-free-1.7.0/src/libraries/qtopia/inlinepics_p.h,发现inlinepics_p.h是空白的,原来是
qembed --images $QPEDIR/pics/inline/*.*
> $QPEDIR/src/libraries/qtopia/inlinepics_p.h
出了错误,重新操作一遍这一步,再查看inlinepics_p.h,发现正常了,要继续交叉编译qtopia:
make clean
./configure –platform linux-arm-g++