windows的动态库有几个需要注意的地方,因为相比较linux的动态库而言,需要设置的地方实在太多了。
1、首先需要注意的是运行时库的模式的选择一定要一致的!
原因在于每个dll库的堆管理器都是建立在运行时库crt的副本的基础之上,而每一个库必然有一个运行时库的副本。这里涉及到几个选择问题。
第一,选择mt还是md的问题,
1)mt表示的是mutilt-thread single,表示的多线程的静态运行时库。如果选择这种模式,需要注意的是每个动态库在程序运行时使用的数据以及堆都是建立在各自的运行时库的副本的基础之上的,换句话说,就是各自使用各自的堆内存,因此每个库使用自己的内存都是老死不相往来的,只有在使用非动态库分配的内存(也即程序主体分配的内存)时才能真正做到通信和访问。如果谁要是越界,就可能存在这样一个风险,例如如果存在这样一种用法:动态库A提供的接口不仅给动态库B使用,还直接给程序主体使用;而此时若动态库A提供的接口中返回一个在其堆中分配的内存块的地址,然后是传给动态库B使用的,但是释放时则是在动态库B传给程序主体的main函数中去释放的,这是由于main使用的动态库A的运行时库的副本是与动态库B所依赖的动态库A的运行时库的副本是不一致的,因此就会出现指针的非法使用,释放了不正确的内存块地址,造成堆损坏。---这种用法的一种更隐蔽的错误用法是:并没有将动态库A的指针返回出去,而是提供了一系列可以操作内部内存堆块的函数接口;但是仍然会出现这样一种错误,即在上述动态库B中使用调用动态库A的接口分配内存去完成某些操作并存储数据,而在程序主体的main函数中去调用动态库A的接口去读取认为已经存储的数据然后操作该数据改写,但是此时由于两个接口调用的副本不一致&#x
1、首先需要注意的是运行时库的模式的选择一定要一致的!
原因在于每个dll库的堆管理器都是建立在运行时库crt的副本的基础之上,而每一个库必然有一个运行时库的副本。这里涉及到几个选择问题。
第一,选择mt还是md的问题,
1)mt表示的是mutilt-thread single,表示的多线程的静态运行时库。如果选择这种模式,需要注意的是每个动态库在程序运行时使用的数据以及堆都是建立在各自的运行时库的副本的基础之上的,换句话说,就是各自使用各自的堆内存,因此每个库使用自己的内存都是老死不相往来的,只有在使用非动态库分配的内存(也即程序主体分配的内存)时才能真正做到通信和访问。如果谁要是越界,就可能存在这样一个风险,例如如果存在这样一种用法:动态库A提供的接口不仅给动态库B使用,还直接给程序主体使用;而此时若动态库A提供的接口中返回一个在其堆中分配的内存块的地址,然后是传给动态库B使用的,但是释放时则是在动态库B传给程序主体的main函数中去释放的,这是由于main使用的动态库A的运行时库的副本是与动态库B所依赖的动态库A的运行时库的副本是不一致的,因此就会出现指针的非法使用,释放了不正确的内存块地址,造成堆损坏。---这种用法的一种更隐蔽的错误用法是:并没有将动态库A的指针返回出去,而是提供了一系列可以操作内部内存堆块的函数接口;但是仍然会出现这样一种错误,即在上述动态库B中使用调用动态库A的接口分配内存去完成某些操作并存储数据,而在程序主体的main函数中去调用动态库A的接口去读取认为已经存储的数据然后操作该数据改写,但是此时由于两个接口调用的副本不一致&#x