C语言的跨平台性及库的跨平台×××

请移步https://higoge.github.io/,全部下载资料在那个博客都能找到。谢谢。 html

这篇文章写的太烂了,仍是别看了。git

--------------------------------------------------------------------github

    啥?C语言是跨平台的?你们刚学C语言的时候,都知道C是不跨平台的。C的跨平台性从何提及?
编程

 

    呵呵,看官莫急,听Jeremiah徐徐道来。ide

 

    本篇博客所讨论的跨平台性,是比较狭义的,主要是讨论跨Windows和Linux这两个最流行的操做系统,确切的说,是跨VC和gcc这两大编译器。在这也只是浅谈一下,不作太深刻的研究。函数

 

    主要内容以下:
    1. C语言的跨平台性
    2. MinGW及Cygwin
    3. GCC制做动态库及静态库及调用方法
    4. VC++制做的静/动态库与GCC制做的动静态库相互替换
测试


    1. C语言的跨平台性
    你们也都知道Java是跨平台的语言,主要是由于在不一样的系统上面安装不一样的JRE,也就是Java运行时环境,这样,相同的代码在不一样的操做系统上面,运行的效果是同样的。
spa

 

    其实Jeremiah所谓的跨平台性,跟Java的这种机制是相似的。主要是编译器GCC的跨平台性。操作系统

 

    看过Jeremiah之前博客的人都应该知道Jeremiah主要研究的是开源项目VLC,顺便研究了点FFmpeg及Live555,这些项目其实都是基于Linux开发的,可是能在Windows上运行主要是借助了两个环境,MinGW及Cygwin。以此类推,若是咱们基调试

于Linux作开发,想要在Windows下运行,那就用MinGW或Cygwin就okay了。Jeremiah之后也将主要从事Linux里的C编程开发。

    2. MinGW及Cygwin
    Google "MinGW Cygwin/Gcc"会出现不少关于MinGW和Cygwin的文章。主要介绍了MinGW和Cygwin这两个Jeremiah所谓的仿真Linux环境的异同。推荐看一下http://blog.classky.com/2008/11/27/difference-of-gcc-compiler-between-MinGW-and-cygwin/http://bbs.lupa.gov.cn/273398/viewspace-122539.html。英文的看这个http://www.delorie.com/howto/cygwin/mno-cygwin-howto.html里面讲的很是的好。

 

    在这Jeremiah写个简单的测试程序说明二者的异同。

InBlock.gif#include <stdio.h>
InBlock.gif
InBlock.gifint main()
InBlock.gif{
InBlock.gif        printf("hello world\n");
InBlock.gif        return 0;
InBlock.gif}

   

    在MinGW和Cygwin下分别执行

gcc -o hello hello.c
./hello

    在各自的环境中,都能运行出hello world来。

    可是若是在cmd下运行Cygwin/GCC编译出来的hello.exe,却说找不到Cygwn1.dll。

   

    在cygwin下编译hello.c的时候加入参数-mno-cygwin,则cmd下运行的时候,就能够正确的执行。

gcc -mno-cygwin -o hello hello.c
./hello

    也就是gcc -mno-cygwin编译出来的程序能够不须要Cygwin1.dll。这也就是为何咱们运行编译完的VLC的时候,没有提示须要这个Cygwin1.dll。由于咱们在configure-vlc.sh中加入了CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"。那是否是说Cygwin的gcc -mno-cygwin与MinGW的gcc是同样的呢?通过Jeremiah的使用,发现,仍是有些许区别的。好比我在Cygwin下用gcc -mno-cygwin编译Live555的就会报错,而在MinGW下编译,就没问题。具体缘由,尚未搞明白。可是通常的程序,仍是能够当作等同的。

    3. GCC制做动态库及静态库及调用方法
    若是是Linux的开发人员,这个东西简直太简单了。我这个标题主要是写给VC++的开发人员的。由于Jeremiah接触了一些VC++的开发人员,发现这些朋友对Linux相关的东西不是太熟悉。因此在这写一个简单的程序来讲明Linux的库的制做及调用。主要的编译器仍是MinGW的Gcc或者是Cygwin的gcc -mno-cygwin。

 

    在当前目录创建文件夹test,下面分别创建两个文件夹lib,及testlib。

mkdir test && cd test && mkdir lib testlib

    在lib下创建add.h及add.c。

InBlock.gif//add.h
InBlock.gifint add(int, int);

 

InBlock.gif//add.c    
InBlock.gif#include "add.h"    
InBlock.gif    
InBlock.gifint add(int x, int y)    
InBlock.gif{    
InBlock.gif        return x + y;    
InBlock.gif}    

    编译生成静态库

gcc -c add.c
ar crs libadd.a add.o

    编译生成动态库

gcc -shared -o libadd.dll add.c

    这样,包含一个add函数的静态库和动态库就创建好了。

 

    在testlib下创建test.c来调用库。

InBlock.gif//test.c    
InBlock.gifinclude <stdio.h>    
InBlock.gif#include "add.h"    
InBlock.gif
InBlock.gifint main()    
InBlock.gif{    
InBlock.gif    printf("result=%d\n", add(3,5));    
InBlock.gif    return 0;    
InBlock.gif}

    执行

gcc -o test test.c -I../lib -L../lib -ladd
./test

    就能获得结果

result=8

    但这只是链接的静态库。

    若是链接动态库呢? VC++的开发人员都知道调用dll的方法,须要LoadLibrary及GetProcAddress这些函数一个个的把dll中的函数导入进来调用。(参考:http://tech.ddvip.com/2007-03/117395352621216.html
    可是在Linux下面就不用,调用动态库与静态库是同样同样的。(Jeremiah很喜欢这样的方式,吼吼)
执行

rm ../lib/libadd.a
gcc -o test test.c -I../lib -L../lib -ladd
./test

会出现问题

    主要是由于动态库的位置咱们没有告诉系统。因此系统调用libadd.dll的时候,找不到它在何处。


    Linux下一般的方法是配置LD_LIBRARY_PATH。

export LD_LIBRARY_PATH=~/test/lib

    可是配置这个环境变量在MinGW和Cygwin是很差用的,仍是会提示找不到libadd.dll。应该配置的环境变量是PATH。

export PATH=~/test/lib:${PATH}
echo $PATH
./test

    这样就能获得结果了。


    4. VC++制做的静/动态库与GCC制做的动静态库相互替换
    这样能够吗?真的能够吗?答案是:能够。


    Jeremiah某日脑子发神经,忽然想研究VC++编译其与MinGW/Gcc的相互调用问题,由于这两个环境编出来的都是Windows下的程序,确定应该存在必定的共性。并且主要是VC++静态库.lib和MinGW/Gcc的静态库.a的关系。


    通过研究,结论是:
    1) MinGW编译生成的动态库libadd.dll,能够被VC++的任何一个环境调用。
    2) Mingw编译生成的静态库libadd.a也能够被被VC++的任何一个环境调用,只不过要本身手动更名字,将libadd.a改成libadd.lib就可使用了。

    3) 将上面的add.h及add.c用VC制做成一个静态库和一个动态库对VC++开发人员是小菜一碟的事情,可是通过测试发现,只有VC6生成的libadd.lib及libadd.dll才能被MinGW/Gcc调用。其余的VS版本没有调试成功,主要是由于MinGW/Gcc和VC6都使用COFF格式,而其余的VS版本,我不知道是啥格式。是否能够调整到这样的格式,还请各位VC++达人告诉我一声。谢谢。

 

    啰啰嗦嗦了这么些,最后的结果就是VLC的那些dll在VC++下是彻底能够被调用到的。下一篇Jeremiah将会介绍用VC++调用libvlc.dll制做MFC的播放器。

相关文章
相关标签/搜索