2018-06-16

源码直接拉下来 https://github.com/bitcoin/bitcoin

比特币的入口函数在src/bitcond.cpp中

int main(int argc, char* argv[])

{

    SetupEnvironment();

    // Connect bitcoind signal handlers

    noui_connect();

    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);

}

bench_bitcoin, bitcoin-cli, bitcoind, bitcoin-qt, bitcoin-tx, test_bitcoin, test_bitcoin-qt。其中第2,3,4,5个是主要的功能部分,所以只需要说bitcoind就行了

这里的函数入口有三个函数。最重要的是APPinit()包含着程序的初始化。

 SetupEnvironment();是环境的设置,比方说现在是32位还是64位,

void SetupEnvironment()

{

#ifdef HAVE_MALLOPT_ARENA_MAX

    if (sizeof(void*) == 4) {  //判断是否为32位系统

        mallopt(M_ARENA_MAX, 1);

    }

#endif

#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)

    try {

        std::locale(""); // Raises a runtime error if current locale is invalid

    } catch (const std::runtime_error&) {

        setenv("LC_ALL", "C", 1);

    }

#endif

    std::locale loc = fs::path::imbue(std::locale::classic());

    fs::path::imbue(loc);

}

以上就是设置比特币环境。那么问来了,是编译环境还是运行环境呢,环境设置写什么呢,这些在网上的一些源码都是一句带过。在这里不行

因为这里重点不是学习比特币,是c++开发。以上设计的内容非常多。

以下以几个内容产开,是c++基础。

第一个是编译和运行的区别。

第二c++内存管理(这个吊)


编译过程,C++编译过程包括预编译-》汇编-》编译-》链接

预编译  

处理 # 开头的指令 ,

比如拷贝 #include 包含的文件代码

#define 宏定义的替换 , 条件编译等、

SetupEnvironment(),这里就是处理一些条件编译的东西。大致的有判断系统的位数,编译环境。以不同的编译环境控制内存分配。

一句话总结。预编译后代码更加短小精湛。预编译的结果还是c++代码。

编译

从一个问题开始。static 全局变量不初始化会不会出错。出错是在编译时刻出错还是运行时刻。

解决上个问题需要知道编译时刻做了什么。

一般常用的编译器, gcc 

编译——链接——install

其中编译时将c++-----到二进制的一个过程

链接是=将所有的二进制文件链接起来。比方说使用没有实现的声明,就在链接报错


在c++到汇编的时候会进行一些语法检查。上面说的static int i 会不会报错。就是在编译器中知否时属于语法错误。 

未初始化的全局变量,静态变量是不会报错的。因为编译器允许。但是会报warnning ,程序员要尽量避免warnnning‘。因为在未来可能warnning就会出错

静态变量,默认初始化是零。为什么呢。

c++机制为什么会把未初始化的全局变量和静态变量初始化为零。大家想想,因为全局变量和全局静态变量。程序运行的时候就已经储存在固定的内存区。如果有程序员遗忘初始化。

那么会导致意想不到和结果。所以机制将这些未初始化的东西初始化为零。

这里有几个问题。自问自答了

一个是char型变量呢。默认初始化为/0

全局指针型变量,默认初始化为null


有些朋友可能去实验过。我定义一个未初始化的变量。但是输出不是零啊

这些朋友可以去深刻理解一下全局变量和局部变量、

问。为什么程序知道从含有主函数那个cpp文件执行呢。

答 。使用linux知道有个makefile 文件。那个是可以认为组织程序编译连接顺序的。

通过以上分析知道、我们分析bitcoind.cpp。相当于我们已经从程序加载后。开始运行的时候分析了、。显然遗漏了预编译,全局变量初始化。还有程序加载到内存中的步骤。

程序加载是什么意思呢。我们之前下载程序还得安装。安装就是程序加载到内存当中。那程序的大小由什么决定的呢。

c++程序五个占内存的区域。堆,栈,代码区。全局变量/静态变量/全局静态变量区 ,常量区。

刚开始运行一个程序的时候,比方qq。常量区。全局变量/静态变量/全局静态变量区 ,代码区都是有内容了的。堆和栈是空着的。在运行过程,堆和栈不断地进行使用。这两个内存使用的效率,灵活性都不一样、这里就不展开了。相信大家都懂。

程序运行的时候。常量和代码区已经是有稳定的二进制数在里面了。,先进行一些全局静态变量的初始化。然后进入主函数。主函数继续进行一些变量的初始化。但是主函数的初始化内容就不是全局变量了。比特币中appinit进去就是一些初始化函数。


在linux下使用make编译链接程序。然后使用make install将程序加载到相应目录。

接下来是一些静态库和动态库的链接:

你可能感兴趣的:(2018-06-16)