• VC++ 配置困惑


    开发的时候,若使用了第三方的库文件,比如在C#中,比如说要访问Sqlite数据库,我们需要将dll文件以及相关的引入到工程文件中,这个所需要的操作就是添加引用。

    但是如果使用VC++的时候,好像并不这么简单,因为在引入第三方的时候,除了dll,可能还会有 lib,h文件等,当然在这里可能没有dll,在这里有必要介绍下dll和lib

     

    .dll是在你的程序运行的时候才连接的文件,因此它是一种比较小的可执行文件格式,.dll还有其他的文件格式如.ocx等,所有的.dll文件都是可执行。


    .lib是在你的程序编译连接的时候就连接的文件,因此你必须告知编译器连接的lib文件在那里。一般来说,与动态连接文件相对比,lib文件也被称为是静态连接库。当你把代码编译成这几种格式的文件时,在以后他们就不可能再被更改。如果你想使用lib文件,就必须:

    1   包含一个对应的头文件告知编译器lib文件里面的具体内容
    2   设置lib文件允许编译器去查找已经编译好的二进制代码


    如果你想从你的代码分离一个dll文件出来代替静态连接库,仍然需要一个lib文件。这个lib文件将被连接到程序告诉操作系统在运行的时候你想用到什么dll文件,一般情况下,lib文件里有相应的dll文件的名字和一个指明dll输出函数入口的顺序表。如果不想用lib文件或者是没有lib文件,可以用WIN32
      API函数LoadLibrary、GetProcAddress。事实上,我们可以在Visual   C++  
    IDE中以二进制形式打开lib文件,大多情况下会看到ASCII码格式的C++函数或一些重载操作的函数名字。

     

    在VC++中,我们可能会碰到两种库,一种就是我们常见的dll,而另一种就是lib结尾的库。

    dll的全称是dynamic link library,是在运行的时候用到的,应用程序在运行的时候动态加载。

    lib文件比较特殊,可以根据是否有dll文件分为两种情况:

    如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容,应用程序使用lib文件链接到dll文件,在应用程序的可执行文件中,存放的不是被调用的函数代码,而是dll中相应函数代码的地址,从而节省了内存资源。dll和lib文件必须随应用程序一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。

    如果只有lib文件,那么这个lib文件是静态编译出来的,这样的文件通常称之为static link library,索引和实现都在其中。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。


    使用lib需注意两个文件:
    (1).h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
    (2).lib文件,略。

    使用dll需注意三个文件:
    (1).h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
    (2).lib文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载(显示连接,有没有考虑搜索dll的顺序)。
    (3).dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。


    在VC++中配置的时候,引入头文件这个是不用说的,因为不管是dll还是lib,都需要有这个.h的文件,在配置的时候需要将.h所在的文件作为包含目录,一般就是在VC++目录这个选项配置,在VC++配置的时候可以指定下列目录类型。                       

    可执行目录             搜索可执行文件的目录。                   对应于 PATH 环境变量。 
    包含目录              搜索在源代码中引用的包含文件的目录。                   对应于 INCLUDE 环境变量。 
    引用目录              搜索通过 #using 指令在源代码中引用的程序集和模块(元数据)文件的目录。                   对应于 LIBPATH 环境变量。 
    库目录                搜索库(包括运行时库)的目录。                   对应于 LIB环境变量。                      
    源目录                搜索用于 IntelliSense 的源文件的目录。                               
    排除目录              检查生成依赖项时,不会搜索目录。

    现在又有问题出来了,我们知道C++中.h文件相当于一个声明文件或者元数据文件,但是真正执行的代码是在cpp文件中,只有.h文件肯定是不行的,还需要库文件,要不然会在运行的时候经常遇到"link error" 的错误,这既是因为没有设置lib文件造成的,在连接器中的附加链接库中添加需要的lib,当然也可以在程序中通过

    #pragma comment(lib,"liuyu.lib") 来设置

    又有一个问题,这个lib文件的路径是在什么地方?

    在这里有几个需要区分,也有几个我不太明白的,我只是将疑惑贴上来:

    C/C++附加包含目录和VC++目录包含目录区别?
    连接器常规附加库目录和VC++目录库目录区别?
    
    
    附加依赖项:指输入项,如某个.lib文件liuyu.lib,添加到附加依赖项,你的lib文件被真正包含进来了。等同于“#pragma comment(lib, "liuyu.lib") ”语句
    附加库目录:也就是附加依赖项所在的目录,当用#pragma comment(lib,"liuyu.lib")的时候;此时就搜索liuyu.lib的路径列表就包含这个路径。
    
    但是上面的困惑我还不清楚.我猜测这几个配置是一样的。经过我的搜索,询问,找到一篇帖子,原来是搜索顺序不一样,其实效果是一样的。
    连接如下:http://blog.csdn.net/cppyin/article/details/6225596

     

    The compiler searches for directories in the following order:

    1.Directories containing the source file.

    2.Directories specified with the /I option, in the order that CL encounters them.

    3.Directories specified in the INCLUDE environment variable.

    order2中的/I是由C/C++ -> General -> Additional Include Directories设置的。

    order3中的INCLUDE是由VC++ Directories -> Include Directories设置的。

    
    

    记得以前在博客中写过搜索dll的顺序,这里再推荐一篇:http://www.cnblogs.com/lidabo/archive/2012/07/12/2587567.html
     

  • 相关阅读:
    Redis Linux版安装详解
    cdh-hbase用户无法执行命令
    异常-java.util.concurrent.TimeoutException: Futures timed out after [100000 milliseconds]
    异常-Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): Permission denied: user=hdfs, access=WRITE, inode="/hbase":root:supergroup:drwxr-xr-x
    【异常】Maxwell异常 Exception in thread "main" net.sf.jsqlparser.parser.TokenMgrError: Lexical error at line 1, column 596. Encountered: <EOF> after : ""
    【异常】jps6432 -- process information unavailable
    异常-Exception in thread "main" net.sf.jsqlparser.parser.TokenMgrError: Lexical error at line 1, column 596. Encountered: <EOF> after :
    【异常】java.sql.SQLException: Could not retrieve transaction read-only status from server Query
    【异常】ser class threw exception: java.sql.SQLException: The last packet successfully received from the server was 39,444 milliseconds ago. The last
    storedownloadd占用cpu高
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/3060744.html
Copyright © 2020-2023  润新知