CC++编程答疑解惑_第1页
CC++编程答疑解惑_第2页
CC++编程答疑解惑_第3页
CC++编程答疑解惑_第4页
CC++编程答疑解惑_第5页
已阅读5页,还剩283页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C/C+编程答疑解惑1.C/C+编程1.1: 遇到问题怎么解决 A 论坛的精华区也有相应的讨论,许多可以直接解决你的问题,也可以GOOGLE查找,并看看精华区。 如果已找了GOOGLE并看了精华区,但是对某些方面不理解,那么就在论坛上发问。发问时标题要清楚,并把你的问题描述清楚。许多人不会看你帖子的内容,所以在标题中写清楚问题也是很重要的。 如果要粘贴代码,那么使用发言功能中的CODE功能,这样可以保证代码不会乱,能有更多人看懂你代码。 当别人准确回答了你的问题时,应该说声谢谢,表示这个问题已回答,并表示对帮助你的人的感谢。这样会让更多的人觉得你的一个好学有礼貌的人,从而会更注意你的问题。 如

2、果你按上面这些方法做了,并不能保证你的发言一定能回答,因为不是每个人什么问题都知道,但可以保证会有更多人关注你的问题,回答的可能性会更高。 1.2:STL string 怎么转换大小写 A:使用STL算法中的transform 函数 代码:   string str22 = "This IS a MiXed CaSE stRINg"    transform (str22.begin(),str22.end(), str22.begin(), tolower); 1.3: 怎样生成动态库 A:创建步骤: 首先创建object文件,这个

3、文件将加入通过gcc fPIC 参数命令加入到共享函数库里面。PIC的意思是“位置无关代码”(Position Independent Code)。下面是一个标准的格式: 代码:gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list 下面再给一个例子,它创建两个object文件(a.o和b.o),然后创建一个包含a.o和b.o的共享函数库。例子中”-g”和“Wall”参数不是必须的。 代码:gcc -fPIC -g -c -Wall a.c gcc -fPIC -g -c -Wall b.c gcc

4、-shared -Wl,-soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o -lc 下面是一些需要注意的地方: · 不用使用-fomit-frame-pointer这个编译参数除非你不得不这样。虽然使用了这个参数获得的函数库仍然可以使用,但是这使得调试程序几乎没有用,无法跟踪调试。 · 使用-fPIC来产生代码。 使用shared 说明生成动态库,使用soname说明生成的库名 · 某些情况下,使用gcc 来生成object文件,需要使用“-Wl,-export-dynamic”这个选项参数

5、。通常,动态函数库的符号表里面包含了这些动态的对象的符号。这个选项在创建ELF格式的文件时候,会将所有的符号加入到动态符号表中。可以参考ld的帮助获得更详细的说明。 star3s补充: 对于C+程序要使用EXTERN “C”说明输出接口 代码:   extern "C"          int soTest(int a,int b) ;        int soTest(int a,int b)         

6、 return a+b;     1.4:怎样指定程序链接某个库的动态库或静态库版本 A:使用Bdynamic和-Bstatic选项。默认情况下,假如共享库可用,连接器会使用共享库。但是-Bdynamic和-Bstatic提供了很好控制库的方法。它们可以决定用共享库还是用静态库。 传-Bdynamic和-Bstatic选项给连接器,如下操作: # gcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar # gcc -o main main.o -Wl,-Bstatic 告诉连接器所有的库(象libc等等)都使用静态

7、的版本。 1.5: 请问各UNIX平台下和编译器名 kaisakaisa : sun CC (c+) cc(c) alpha cxx(c+) cc(c) HP aCC(c+) IBM xlC (c+) 1.6: solaris下有没有C函数可以获得进程的相关信息 比如:进程名、进程pid、进程所占CPU/Memory、开始时间、运行状态等等。谢谢。 liupch:2003-03-19 10:03 读取/proc/进程号/psinfo这个文件。 就用我告诉你的那个函数 ioctl(fd, PIOCPSINFO, &procinfo); 在看一下procinfo这个结构就知道了。 1.7:

8、 c+下使用<iostream>的问题 在c+下使用include <iostream>后为什么编译器会报错呢 1.检查你是不是使用g+编译器编译。gcc编c+程序会有问题 2.检查在include 头文件后有没有使用using namespace std; 新的标准C+加了几个关键字,其中最常用的就是namespace(名字空间) 加入这个关键字是为了避免在大程序中符号名重定义问题 同时原来的标准c+类都包含在std 名字空间中(如果使用c+ 的标准函数库,如<cstdio> 那么它们也在std名字空间中) 新的标准c+头文件没有 .h,所以当你们incl

9、ude它们时要注意使用std名字空间. 以下一个例子 代码:#nclude <iostream> #include <string> using namespace std;  /在include 所有标准c+头文件后 main()     cout<<"hello world"<<endl; 1.8 :volatile的作用是什么 volatile的本意是“易变的” 由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。 一般说来,volatile用在如下的几个地方:

10、1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义; 另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。 简单点: 就是该变量会以编译器无法预知的方式发生变化,请编译器不要做优化(所有的编译器的优化均假设编译器知道变量的变化规律) 1.9: 请问,用 gcc 或 ld 连接程序时,如何设置段的属性? 幽

11、灵兵: 为了实现共享数据,这个方法要比其它 进程/线程 的数据同步方法更 快,更方便,更灵活,而且是所有方法中最简单的。 比如我在 Win 下这样做: 1. 创建个 DLL 专门用于数据交换 2. 在 DLL 中声明一个全局变量 Var1 3. 在连接时声明 .bss 段为共享段 ( Vc Linker: /section:.bss,S | Gcc: type Var1 _attrbiute_ (section("shared"), shared); ) 4. 在需要这个变量的进程中调用这个 DLL . . 其实就是将这个DLL作为一种数据池. 难道你们没用过吗? 我想将

12、.bss 段设置为 共享,gcc 在 NT 下可以用: int Var _attrbiute_ (section("shared"), shared); 在 Linux/UNIX 下怎么办呢? JohnBull :2003-04-27 Linux系统并不强调“段”的使用,因为Linux的设计者考虑到这个OS将移植到包括RISC等多种平台上,而事实上只有Intel的CPU才强调“段”的概念,其他(包括大多数64位)系统都是基于“页”进行设计的。 在Linux中,请用共享内存。 2.数据库编程2.1:如何在pro*c中调用存储过程 ilmare : 在嵌入式SQL中使用CALL

13、 语句调用存储过程的格式如下: 代码:EXEC SQL CALL schema. package. stored_procdb_link (arg1, .) INTO :ret_var INDICATOR :ret_ind; 例子: 创建一个PL/SQL函数fact,该函数存储于mathpkg包中 代码:EXEC SQL CREATE OR REPLACE PACKAGE BODY mathpkg as function fact(n IN INTEGER) RETURN INTEGER AS BEGIN IF (n <= 0) then return 1; ELSE return n

14、* fact(n - 1); END IF; END fact; END mathpkg; END-EXEC. 使用该函数 . int num, fact; . EXEC SQL CALL mathpkg.fact(:num) INTO :fact; . 2.2: 请问在pro*c中知道错误代码,怎么查这个代码的错误信息? mengwg : 在sql*plus中使用>oerr ora 1013 CHUJUN_98: sqlca中含有中文含义 sqlca.sqlerrm.sqlerrmc代表的是sqlCZHI行的结果描述 2.3: AIX下编译的嵌入式DB2 C程序,删除数据库后再创建时连

15、接不成功 预编译:embprep proc 得到proc.bnd和proc.c文件,编译没有错误发生。 编译:xlc -o proc proc.c -ldb2 编译正确,生成执行文件proc。 执行proc一切正常。 因为涉及到可能的移植问题,于是测试将数据库Emp Drop掉(db2 drop database Emp),再重新建原来相同的数据库Emp和表info,建成后执行proc,程序可正常连接数据库,可在对表info操作时(如select)返回SQLCODE错误=-805,也就是说无法对表进行操作。重新编译该程序后,运行正常! AIX 下的DB2数据库不太好用,它在编译时会产生一个PK

16、G存放于数据库中, 并且会对它打上时间戳。如果从新建库获建表的话都会破坏时间戳,必须从新编译或rebind,以产生新的PKG。 hasjing:2003-03-17 12:55 AIX 下的DB2数据库不太好用,它在编译时会产生一个PKG存放于数据库中, 并且会对它打上时间戳。如果从新建库获建表的话都会破坏时间戳,必须从新编译或rebind,以产生新的PKG。 时间戳的目的是为了保证db2数据库优化策略的一致性,而且PKG的内部名称 是SQC文件的前八个字母,所以在开发时要当心每个模块的名字前八个字母不能相同!否则会产生PKG覆盖,会产生818的错误代码! 所以IBM的东西虽好,但是规矩太多!

17、 在db2环境下 ? SQL0805 可以查看错误代码! 2.4: 请问SOLARIS下使用OCI编程序要连什么库 在Solaris8下安装了oracle8.1.6,并编译用OCI编写的程序,其中使用了很多的oci函数,包括Direct Path API,但联接时,提示OCIDirPathColArrayReset'等符号找不到 编译时已加入了-L/export/home/opt/oracle/8.1.6/lib -lclntsh 如果将Direct Path的调用去掉,则连接成功,请各位高手不吝赐教 wangz :2003-03-20 加上-lclient8就可以了!试试看,我这里可

18、以 2.5:请问怎样用ct-librery编程 有哪位熟悉ct-library编程,我在写有关socket通讯的程序,需要和sybase数据库交互信息。希望和高手切磋一下! minsanyuan :2003-04-21 22:55 调CT-Library就可以了,那来的socket呀, 如果用socket就不要用ct-Library了, 如果你很牛,可以试试两都都用 1. 初始化ct-library ct_init( .) 2. 分配连接结构 ct_con_alloc(.) 3. 设置用户名及口令 ct_con_props(.) 4. 建立连接 ct_connect(.) 5. 断开连接 ct

19、_exit( . ) 6. 释放 ct_ctx_drop(.) /Sybase/sample下有例子 3 GTK+ 编程 以下由付强提供,QQ:775341 ,感谢他把自己的学习成果写出来与大家分享 原作者声明如下 > 这些文章其实是我的学习笔记,以 FAQ方式代问自答,希 > 望能帮初学者解决一点实际问题。 > 您可以随意修改或转载本文,但请保证内容的正确性,以 > 免误人子弟 - 谢谢 :) 3.1问:论坛中有人说 GTK+ 并不支持中文,是这样吗? - 答: GTK+ 采用 UTF-8 编码就是为了支持多字节文字,所以GTK+ 肯定支持中文,而且非常出色,你可以看

20、到网上使用 GTK+ 编写 的中文软件数不胜数,所以没必要理会那种说法。 ( 我真的看过这类的帖子,误人子弟.呵呵. ) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.

21、2问:为什么在控件上的汉字无法显示,并伴有如下错误警告: "* (:1864): WARNING *: Invalid UTF8 string passed to pango_layout_set_text()" - 答: GTK+ 中的字符串均采用 UTF-8 格式编码,这个提示就是告 诉您,程序中的字符串编码格式不是 UTF-8,通常这是由编辑器 造成的,例如在我的 VC7 中,默认的存档编码格式为 GB2312。 但是,除了将文件以 UTF-8编码格式存档外,你还可以使用 glib 的转换函数在程序的运行过程中将字符串转换为 UTF-8。 例如: 将 button =

22、 gtk_button_new_with_label( "确定" ); 改成 button = gtk_button_new_with_label( g_locale_to_utf8("确定",4,NULL,NULL,NULL); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

23、>>>>>>>>>>>>>>>>>> 3.3问:为什么在屏幕上输出的汉字变成了乱码? - 答: 既然可以显示乱码,就表明与编码格式无关。 您可能已经想到了 - 对,问题就出在字体上。 一般情况下,系统会用"Sans"作为默认字体,但这种字体中 只包含了 ASCII 码,所以汉字是无法显示的。 >>>>>>>>>>>>>>>>>>>>>>&

24、gt;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.4问: 在修改控件字体的第一步就发生了错误,gdk_font_load() 总是失败,为什么? - 答: 首先向您提供一些建议: 1.不要用 GDK 的一些函数更改字体,因为那是 GTK+的不稳定 因素之一(至少在2.0以下版本中是这样的)。 2.为了获得更多的字体,应该避免使用 GdkFont类型

25、,及相关 函数,取而代之的是 Pango 库,这是 GTK+ 的一部分。 3.GdkFont 只能使用 XFont 字体,而且使用方法相对复杂, PangoFontDescription 可以使用 XFont,以及一些本地字体, 包括 Win Font, XRender Font, TrueType Font,所以您没有必 要再留恋 GdkFont 了。 4.您不需要修改所有控件,更简便的方法是在主窗口创建后立 即修改它的字体,将来创建的控件会继承它的这项属性。 例如: 代码:window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); GtkStyle *s

26、tyle = gtk_rc_get_style( window ); pango_font_description_set_family( style->font_desc, "Stsong" ); gtk_widget_set_style( window, style ); ( 这三句代码是将程序的字体设置为 "华文宋体" ) >>>>>>>>>>>>>>>>>>>>>>>>>>>>

27、;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.5问:我不想使用宋体,怎样获得其它字体的代号? - 答: 部分字体的代号和它的文件名是相同的,例如黑体的代码为 "Simhei",华文宋体为"Stsong"。 您还可以通过一些 Linux/Unix 下的编辑软件的字体选择框 来查找字体对应的代码。 但标准的方法是调用 Pango库中的相应函数来查找机器

28、上已 安装的字体。 如果想了解更多关于 Pango的高级使用方法,请参考它自带 的 API 开发手册。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3.6问:你为什么没有

29、说到 gettext() 及相关国际化标准? 答: 目前国内多数程序员采用这个办法汉化程序,所以我没有必 要再多说。但它不一定对每个人都合适,我通常采用自己管理语 言模块的方法实现国际化,这在很多情况下要比 gettext()更方 便。 4. 系统编程 4.1 我建立共享内存之后,忘记了删除掉。请问:1)如果我不管它,它是由系统自己释放掉么 一颗流星: 我建立共享内存之后,忘记了删除掉。请问:1)如果我不管它,它是由系统自己释放掉么?那么系统管理共享内存的机制是怎样的? 2)能否手动释放?如果能,用什么语句呢? gadfly :2003-04-11 不会自动释放,可以用ipcrm删掉 蓝色键盘

30、:2003-04-18 用shmctl或者ipcrm删除后,只有如下情况出现才会被彻底清除。 *直到最后一个连接进程释放它* 或者 *没有一个进程在attach它* 4.2 请问IPCS显示的各权限位意义 一颗流星: C表示具有什么存取权? 蓝色键盘:2003-04-18 ipcs显示的结果中 标志位是共有11位。其中前两位表示如下: R 表示进程等待msgrcv S 表示进程等待msgsnd D 表明该段IPC资源已经被删除,直到最后一个连接进程释放它(请注意这一点,很多情况下往往无法用ipcrm正常删除IPC资源,原因就在于此) C 在进程attach时,共享内存段已经被清除 - 相应的权

31、限没有被设置 其它的9位表明该段IPC资源的权限信息。这个大家都明白,但是注意 - 表明指定权限没有被设置。 4.3 如何在unix下实现kbhit的功能?谢谢! clilye:如何在unix下实现kbhit的功能?谢谢! fieryfox: 2003-04-29 下面的文字摘自Unix Programming FAQ: 3.2 How can I read single characters from the terminal? = How can I read single characters from the terminal? My program is always waiting

32、 for the user to press <RETURN>'. Terminals are usually in canonical mode, where input is read in lines after it is edited. You may set this into non-canonical mode, where you set how many characters should be read before input is given to your program. You also may set the timer in non-ca

33、nonical mode terminals to 0, this timer flushs your buffer at set intervals. By doing this, you can use getc()' to grab the key pressed immediately by the user. We use tcgetattr()' and tcsetattr()' both of which are defined by POSIX to manipulate the termios' structure. #include <

34、stdlib.h> #include <stdio.h> #include <termios.h> #include <string.h> static struct termios stored; void set_keypress(void) struct termios new; tcgetattr(0,&stored); memcpy(&new,&stored,sizeof(struct termios); /* Disable canonical mode, and set buffer size to 1 byte

35、*/ new.c_lflag &= (ICANON); new.c_ccVTIME = 0; new.c_ccVMIN = 1; tcsetattr(0,TCSANOW,&new); return; void reset_keypress(void) tcsetattr(0,TCSANOW,&stored); return; 3.3 How can I check and see if a key was pressed? = How can I check and see if a key was pressed? On DOS I use the kbhit()&#

36、39; function, but there doesn't seem to be an equivalent? If you set the terminal to single-character mode (see previous answer), then (on most systems) you can use select()' or poll()' to test for readability. 5. Solaris内核编程相关问题 5.1 Solaris内核模块中如何getcwd Q: 在Solaris 7 64-bit内核模块中如何获知一个进程

37、的当前工作目录(cwd),getcwd 并不是一个系统调用 A: Rich Teer <richrite-> 最好通过u->u_cdir获取当前工作目录(cwd)的vnode(v节点)。但这依赖于内核当前上 下文,curproc可能并不对应你期望的进程。 代码:usr/include/sys/user.h typedef struct user . . /* * protected by p_lock */ struct vnode * u_cdir; /* current directory */ struct vnode * u_rdir; /* root directo

38、ry */ 5.2 如何避免一个套接字进入TIME_WAIT状态 Q: 我正在写一个unix server程序,不是daemon,经常需要在命令行上重启它,绝大 多数时候工作正常,但是某些时候会报告"bind: address in use",于是重启失 败。 A: Andrew Gierth <andrewerlenstar.demon.co.uk> server程序总是应该在调用bind()之前设置SO_REUSEADDR套接字选项。至于 TIME_WAIT状态,你无法避免,那是TCP协议的一部分。 Q: 如何避免等待60秒之后才能重启服务 A: Erik

39、Max Francis <max> 使用setsockopt,比如 代码:-  int option = 1;  if ( setsockopt ( masterSocket, SOL_SOCKET, SO_REUSEADDR, &option,                    sizeof( option ) ) < 0 )        die( "setsockopt" );&#

40、160;   -  5.3编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思? A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用 端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息, 指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧 使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期 望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不 可能。 一个套接字由相关五元组构成,协议、

41、本地地址、本地端口、远程地址、远程端 口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组 还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据。必须慎重使 用 SO_REUSEADDR 选项。 5.4在客户机/服务器编程中(TCP/SOCK_STREAM),如何理解TCP自动机 TIME_WAIT 状 态? A: W. Richard Stevens <1999年逝世,享年49岁> 下面我来解释一下 TIME_WAIT 状态,这些在<<Unix Network Programming Vol I>> 中2.6节解释很清

42、楚了。 MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现 都必须选择一个确定的MSL值。RFC 1122建议是2分钟,但BSD传统实现采用了30秒。 TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟。 IP头部有一个TTL,最大值255。尽管TTL的单位不是秒(根本和时间无关),我们仍需 假设,TTL为255的TCP报文在Internet上生存时间不能超过MSL。 TCP报文在传送过程中可能因为路由故障被迫缓冲延迟、选择非最优路径等等,结果 发送方TCP机制开始超时重传。前一个TCP报文可以称为"漫游TCP重复报文&q

43、uot;,后一个 TCP报文可以称为"超时重传TCP重复报文",作为面向连接的可靠协议,TCP实现必须 正确处理这种重复报文,因为二者可能最终都到达。 一个通常的TCP连接终止可以用图描述如下: 代码:client                     server             FIN M  close  ->  (被动关闭)  

44、0;          ACK M+1         <-             FIN N         <-  close             ACK N+1         ->  为什么需要 TIME_W

45、AIT 状态? 假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发 最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连 接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。 代码:  scz 2001-08-31 13:28  先调用close()的一方会进入TIME_WAIT状态    此外,考虑一种情况,TCP实现可能面临先后两个同样的相关五元组。如果前一个连 接处在 TIME_WAIT 状态,而允

46、许另一个拥有相同相关五元组的连接出现,可能处理 TCP报文时,两个连接互相干扰。使用 SO_REUSEADDR 选项就需要考虑这种情况。 为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间? 如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。 第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二 个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT 状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。 A: 小四

47、<scz> 在Solaris 7下有内核参数对应 TIME_WAIT 状态保持时间 # ndd -get /dev/tcp tcp_time_wait_interval 240000 # ndd -set /dev/tcp tcp_time_wait_interval 1000 缺省设置是240000ms,也就是4分钟。如果用ndd修改这个值,最小只能设置到1000ms, 也就是1秒。显然内核做了限制,需要Kernel Hacking。 # echo "tcp_param_arr/W 0t0" | adb -kw /dev/ksyms /dev/mem phys

48、mem 3b72 tcp_param_arr: 0x3e8 = 0x0 # ndd -set /dev/tcp tcp_time_wait_interval 0 我不知道这样做有什么灾难性后果,参看<<Unix编程/应用问答中文版>>的声明。 5.5TIME_WAIT 状态保持时间为0会有什么灾难性后果?在普遍的现实应用中,好象也 就是服务器不稳定点,不见得有什么灾难性后果吧? D: rain Linux 内核源码 /usr/src/linux/include/net/tcp.h 中 #define TCP_TIMEWAIT_LEN (60*HZ) /* how lon

49、g to wait to successfully * close the socket, about 60 seconds */ 最好不要改为0,改成1。端口分配是从上一次分配的端口号+1开始分配的,所以一般 不会有什么问题。端口分配算法在tcp_ipv4.c中tcp_v4_get_port中。 5.6结构在优化编译中的对齐问题 Q: 我正在写一个流模块,其中用到了#pragma pack(),当使用 gcc -D_KERNEL -c abc.c ld -r -o abc abc.o 编译链接时,一切正常。为了获得64-bit模块,我必须使用Sun Workshop 5.0, 结果导致系统崩

50、溃。访问 上面说必须在编译链接应用程序的时候指定"-misalign",所以我用了如下命令编译 /opt/SUNWspro/bin/cc -D_KERNEL -misalign -c abc.c /usr/ccs/bin/ld -r -o abc abc.o 但是我不知道该如何在链接时指定"-misalign"。使用的是"/usr/ccs/bin/ld"。 A: Casper H.S. Dik - Network Security Engineer <Casper.DikHolland.Sun.Com> "-mi

51、salign"仅仅用于应用程序,无法应用到内核编程中。"-misalign"使得编译 获得的代码增加了一些runtime glue,它们将指示内核模拟unaligned load(慢)。 作为内核编程,没有等效技术。 Q: 使用#pragma pack()是因为需要读取来自Windows客户端的报文,对端使用 #pragma pack(1)压缩了所使用的数据结构 代码:   #pragma pack(1)     typedef struct pkt_hdr_struct     &#

52、160;        uint8_t  pkt_ver;         uint32_t pkt_type;         uint32_t pkt_len;      pkt_hdr_t;     #pragma pack()  为了采用这个结构读取网络数据,Solaris端的服务程序需要强制转换匹配该结构, 但是一旦企图读取紧接在pkt_ver成员之后的pkt_typ

53、e成员,崩溃了。尝试过其他 办法,首先用一个字符指针读取第一个字节,然后指针增一,把该指针强制类型 转换成( uint32_t * ),然后读取数据,依然崩溃。 此外,是否意味着无法在内核模块编程中使用#pragma pack() A: Ed L Cashin <> 我想你可以单独写一个pkt_header_read()函数,单字节读取然后拼装成相应的数 据类型。如果你想避免函数调用,可以使用"inline"关键字。 A: Casper H.S. Dik - Network Security Engineer <Casp

54、er.DikHolland.Sun.Com> 你是否意识到pkt_hdr_t结构使得你必须自己转换字节序(对端是x86平台) 我不认为#pragma pack()是最好的解决办法,考虑定义如下结构 代码:  struct phs              char ver;         char type4;         char len4;      

55、 采用memcpy()读取数据 memcpy( &phs.type0, &pkt.pkt_type, 4 ); A: Andrew Gabriel <andrewcucumber.demon.co.uk> 采用字符指针是正确的,但是你犯了个错误,编写如下函数 代码:int read_misaligned_int ( int * iptr )              int    i;         int 

56、;   value;         char * ptr  = ( char * )iptr;         char * vptr = ( char * )&         for ( i = 0; i < sizeof( int ); i+ )                      

57、;*vptr+ = *ptr+;                  return( value );       此外,既然你提到对端是x86平台,可能还需要考虑字节序转换的问题 A: W. Richard Stevens <1999年逝世,享年49岁> 代码:/*  * return value:  *     1 big-endian  *     2

58、 little-endian  *     3 unknow  *     4 sizeof( short ) != 2  */  static int byte_order ( void )        union                short s;          char  c sizeof( s

59、hort ) ;      un;      un.s = 0x0201;      if ( 2 = sizeof( short ) )                if ( ( 2 = un.c0 ) && ( 1 = un.c1 ) )                        p

60、uts( "big-endian" );              return( 1 );                    else if ( ( 1 = un.c0 ) && ( 2 = un.c1 ) )                        puts(

61、 "little-endian" );              return( 2 );                    else                        puts( "unknow" );      

62、0;       return( 3 );                      else                puts( "sizeof( short ) = %d", sizeof( short ) );          return( 4 );      &

63、#160;     return( 3 );    /* end of byte_order */  D: CERNET 华中地区网络中心 程序设计版 集体讨论汇总 为了解决Unix自定义结构在GCC优化编译中对齐问题,一般解决办法是用如下宏封装 自定义结构 代码:#pragma pack(1) struct my_arphdr ; #pragma pack() 如果是SPARC/Solaris,还可以这样 代码:struct my_arphdr _attribute_ (packed); 两种办法其实都可以用在Unix系统/GCC编译器中。

64、D: mbufsmth 关于结构中字节对齐问题,相应编译器选项为 GCC/G+ : -fpack-struct Sun Workshop cc/CC: -misalign 最好不这样做,会大大降低程序效率,特别在某些架构中。应该尝试用位操作来处理。 D: Unknownsmth GCC可以这么解决 代码:#ifdef _GCC_ #define PACKED _attribute_(_packed_) #else #define PACKED #endif struct msg    u_int16_t PACKED first;    . ; 还是 V

65、C 简单,#include <pshpack1.h> 就搞定了 A: gfh_nuaa DEC : #pragma pack(1) SUN : #pragma pack(1) AIX : 编译时 -q align=packed HP-UX : #pragma pack 1 D: Joe Durusau 在 Visual C+ 中,使用 "-ZP1" 就可以让编译器对自定义结构进行单字节对齐,实 际就是取消了对齐优化。 A: 2001-12-20 13:09 1) 结构内部成员的pack 代码:struct foo        char a;      int  b _attribute_ (packed);  ;  2) 整个结构的pack 代码:struct

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论