apue中出现的问题及解决方法

如何编译使用其他文件里的函数:

首先使用gcc clconn.c -c  -I.. -L.. -lapue 编译出目标文件clconn.o

然后gcc -I.. -L.. ruptime.c -o ruptime clconn.o -lapue 使用以及编译出来的clconn.o

8.指定编译选项-fPIC 创建独立的(无关联的)地址信息代码。

当创建动态链接库时,独立位置信息(position independent)代码也需要生成。这可以帮助动态链接库或者跟多的加载地址信息来替代其他相对的地址信息。所以-fPIC这个选项作用很大,能快速准确定位错误地址。

下面是一个例子,

  1. $ gcc -c -Wall -Werror -fPIC Cfile.c  
  2. $ gcc -shared -o libCfile.so Cfile.o

页可以直接g++ -shared -I /usr/lib/jvm/java-6-openjdk/include jni_helloworldImpl.cpp -o libHello.so直接用-o来生成so文件

指定编译选项-ansi,支持ISO C89 programs.

通过-ansi选项开启支ISO C89风格.

在这里编译JNI的时候将PATH加上-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux按道理是可以的,但是最后还是讲相关文件拷贝到当前文件夹才编译成功了。

解决Exception in thread "main" java.lang.UnsatisfiedLinkError: no testdll.so in java.library.path 这是因为lib不在System.out.println(System.getProperty("java.library.path")),所以要将lib拷贝到比如/usr/lib中去。也可以使用:

java -Djava.library.path=. com.magc.jni.HelloWorld将java lib path改为当前目录。

解决undefined symbol: __gxx_personality_v0,

“Java Native Interface Programmer's Guide and Specification”一书的第九章提供了一个Java调用C的通用框架,但是没有提供linux的实现,只支持windows和solaris。 在将该框架移植到linux以后,编译顺利通过。可是在运行时却发生了如标题所示的异常。

?

__gxx_personality_v0 is part of the G++ exception handling model defined
by the new C++ ABI in GCC.? The symbol is provided by the libstdc++
library, which is added to the link line by g++.? If you have a C++
routine using exceptions and link with Java, libstdc++.so may not be
referenced and the C++ support routines not found.??

You can inform the compiler that Java exceptions are to be used in a
translation unit, irrespective of what it might think, by writing
`#pragma GCC java_exceptions' at the head of the file.? This `#pragma'
must appear before any functions that throw or catch exceptions, or run
destructors when exceptions are thrown through them.

?

根 据网上的说法,这个问题产生的原因是java和c++的异常模型不一致,导致没有链接libstdc++.so。可是我加了'#pragma GCC java_exceptions'以后还是不行。这是什么原因呢?弄了半天,原来是我在编译时的命令有误。我用gcc编译和链接c++文件,结果就没有自 动链接上c++的标准库。把命令改为g++问题就迎刃而解了。此外我还发现了一个偏门的解决办法,就是编译和链接的时候还是用gcc命令,但是链接的时候 加上-lstdc++就行了。

在h头文件中没有写上参数名,如env和cla,在c文件需要补上,C++不需要也不会报错error: parameter name omitted。

 

Link with shared libraries using -l option

 

The option -l can be used to link with shared libraries. For example:

 

gcc  -Wall main.c -o main -lCPPfile

 

The gcc command mentioned above links the code main.c with the shared library libCPPfile.so to produce the final executable ‘main’. 但是要把libCPPfile.so拷贝到lib目录中,或者修改环境变量,能让gcc找到这个共享文件。

 

 

APUE2e第16.5节ruptime程序运行失败的问题总结 :

出现这种原因是因为没有给服务分配端口号,可以手动添加端口号,就是在/etc/services文件里加上一行:

   ruptime   4000/tcp    就可以了。

   说明一下:

                      ruptime 是服务名,就是getaddrinfo的第二个参数名,而不是程序名。4000是分配的端口号,可以任意,但不要与其他

                      服务的一样,还有就是不能小于1024。tcp就是协议了。

       这里有篇文章参考:

                                    http://blog.csdn.net/andyxie407/archive/2007/06/30/1672325.aspx

可以使用16.9.out www.baidu.com http来得到百度的提供http服务的ip地址。

 

一、简单的讲 gdb如何处理带参数的调试
如果运行 $gdb ./a.out 1 2 3 肯定会报错。正确的做法是:
 
$gdb --args ./A V1 V2 V3
$gdb ./A,进入gdb后  r V1 V2 V3
$gdb ./A,进入gdb后  设置参数set args V1 V2 V3 再直接 r。
 
perror(argv[1]) The perror function produces an error message on the standard error, based on
the current value of errno, and returns.
 
syslog记录在/var/log/messages
 
fprintf(stderr, "read %d bytes\n", ntowrite); 使用fprintf可以写到文件中或者终端。
sprintf(buf, "error: %s\n", strerror(errno));
The printf function writes to the standard output, fprintf writes to the specified
stream, dprintf writes to the specified file descriptor, and sprintf places the
formatted characters in the array buf. The sprintf function automatically appends a
null byte at the end of the array, but this null byte is not included in the return value.
 
启动一个程序execl("/usr/bin/uptime", "uptime", (char *)0);
gdb调试;set args, info locals打印出当前函数中所有局部变量及其值。  p i 打印变量i的值,print命令简写
 
面向连接编程:
server:1. 通过函数得到服务器地址getaddrinfo; 2. 建立并初始化一个套接字fd=socket() bind(fd,addr), listen(fd)。3.等待到来的请求并做下一步动作clfd=accept(fd)这里的fd和第二步建立的fd是同一个,比如发送数据给client, send(clfd)。
client:1. 首先通过函数getaddrinfo得到服务器地址,2. 建立fd=socket(),然后bind(fd, addr),3.最后使用recv(fd)来接受数据。
面向无连接编程:
区别在于没有connect这一步。另外在发送数据的时候需要带上目的地址。
 
如何打包目标文件:ar rv  *.o libapue.a
-d  删除备存文件中的成员文件。
 -m  变更成员文件在备存文件中的次序。
 -p  显示备存文件中的成员文件内容。
 -q  将问家附加在备存文件末端。
 -r  将文件插入备存文件中。
 -t  显示备存文件中所包含的文件。
 -x  自备存文件中取出成员文件。
 选项参数
 a<成员文件>  将文件插入备存文件中指定的成员文件之后。
 b<成员文件>  将文件插入备存文件中指定的成员文件之前。
 c  建立备存文件。
 f  为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入备存文件中过长的成员文件名称。
 i<成员文件>  将问家插入备存文件中指定的成员文件之前。
 o  保留备存文件中文件的日期。
 s  若备存文件中包含了对象模式,可利用此参数建立备存文件的符号表。
 S  不产生符号表。
 u  只将日期较新文件插入备存文件中。
 v  程序执行时显示详细的信息。
 V  显示版本信息。
 
centos支持的stat 结构:
struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* total size, in bytes */
               blksize_t st_blksize; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };

st_mode是用特征位来表示文件类型的,特征位的定义如下:

    S_IFMT      0170000     文件类型的位遮罩  
    S_IFSOCK    0140000     socket  
    S_IFLNK     0120000     符号链接(symbolic link)  
    S_IFREG     0100000     一般文件  
    S_IFBLK     0060000     区块装置(block device)  
    S_IFDIR     0040000     目录  
    S_IFCHR     0020000     字符装置(character device)  
    S_IFIFO     0010000     先进先出(fifo)  
    S_ISUID     0004000     文件的(set user-id on execution)位  
    S_ISGID     0002000     文件的(set group-id on execution)位  
    S_ISVTX     0001000     文件的sticky位  
    S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)  
    S_IRUSR     00400       文件所有者具可读取权限  
    S_IWUSR     00200       文件所有者具可写入权限  
    S_IXUSR     00100       文件所有者具可执行权限  
    S_IRWXG     00070       用户组的遮罩值(即所有权限值)  
    S_IRGRP     00040       用户组具可读取权限  
    S_IWGRP     00020       用户组具可写入权限  
    S_IXGRP     00010       用户组具可执行权限  
    S_IRWXO     00007       其他用户的遮罩值(即所有权限值)  
    S_IROTH     00004       其他用户具可读取权限  
    S_IWOTH     00002       其他用户具可写入权限  
    S_IXOTH     00001       其他用户具可执行权限  

如何得到当前运行进程的数目,有两种方法:
1. ps auxw|wc -l 通过ps然后wc统计出有多少行就有多少个进程
2. ls /proc | grep  "[0-9]" -n 通过ls /proc目录下是数字的文件,也就是pid。
 
when a process terminates, either normally or abnormally, the kernel notifies the parent by sending the SIGCHLD signal to the parent.
 
exit() 是个库文件。
要消除此警告,应包含头文件,stdlib.h

一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
二、结构体大小必须是所有成员大小的整数倍。
如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。看下面的例子,
struct temp
       {
       short i;    +1
       struct
       {
          char c;  +5
          int j;   +6
       } ss;       +10+2
          int k;   +4
};             =16
结构体temp的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。
 
查看centos版本的命令:cat /etc/os-release   cat /etc/redhat-release
 
size_t strlen ( const char * str );
Get string length
Returns the length of the C string str.

The length of a C string is determined by the terminating null-character: A C string is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself).
 

CR的意思是:carriage return,马车返回,也就是回车的意思(翻译是从这里来的,英文取的应该是引申的意义)

LF的意思是:line feed:行满了,也就是说本行已满,下面的内容为下一行的(这就是要换行的意思了)

<CR>   0x0D  13  '/r'

<LF>   0x0A  10  '/n' (有的ASCII 写作 <NL>,也就是new line的意思,这样似乎好理解下)

转载于:https://www.cnblogs.com/qiaolong/p/4801215.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值