如何编译使用其他文件里的函数:
首先使用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这个选项作用很大,能快速准确定位错误地址。
下面是一个例子,
- $ gcc -c -Wall -Werror -fPIC Cfile.c
- $ 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地址。
the current value of errno, and returns.
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.
-m 变更成员文件在备存文件中的次序。
-p 显示备存文件中的成员文件内容。
-q 将问家附加在备存文件末端。
-r 将文件插入备存文件中。
-t 显示备存文件中所包含的文件。
-x 自备存文件中取出成员文件。
选项参数
a<成员文件> 将文件插入备存文件中指定的成员文件之后。
b<成员文件> 将文件插入备存文件中指定的成员文件之前。
c 建立备存文件。
f 为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入备存文件中过长的成员文件名称。
i<成员文件> 将问家插入备存文件中指定的成员文件之前。
o 保留备存文件中文件的日期。
s 若备存文件中包含了对象模式,可利用此参数建立备存文件的符号表。
S 不产生符号表。
u 只将日期较新文件插入备存文件中。
v 程序执行时显示详细的信息。
V 显示版本信息。
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 其他用户具可执行权限
如何得到当前运行进程的数目,有两种方法:
要消除此警告,应包含头文件,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。
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的意思,这样似乎好理解下)