小编T P*_*ers的帖子

使用Visual Studio 2010,如何链接到Visual Studio 2008生成的DLL

我的问题是:

  • 是否可以使用VS2010链接到VS2008生成的DLL?

  • 如果没有,为什么似乎可以链接到VS2008生成的静态库.

  • 我看到VS2010现在有一个Platform Toolset选项.但是,即使他们没有安装VS2008,人们会将它设置为v90而不是v100吗?

  • 即使我使用/ Z7编译器开关,为什么我仍然需要一个.pdb来调试DLL.

细节

我可以使用Visual Studio 2010链接到Visual Studio 2008生成的Leptonica C静态库,没有任何问题.(有关如何构建Leptonica并链接到它的详细信息,请参阅下面的参考部分.)

但是,当我尝试将同一程序(leptonlib-1.67\prog\ioformats_reg.c)与我的VS2008生成的Leptonica DLL版本链接时程序崩溃.调试,我可以看到问题是ioformats_reg.c这样做:

fp = fopen(filename, "rb"); /* in ioformats_reg.c */
Run Code Online (Sandbox Code Playgroud)

不久之后,在leptonlib.dll中完成以下操作,崩溃:

rewind(fp);                 /* in leptonlib.dll */
Run Code Online (Sandbox Code Playgroud)

如何链接正确的C运行时(CRT)库 说:

可重用的库及其所有用户应使用相同的CRT库类型,因此编译器切换相同...

如果您确实选择混合使用CRT库,请记住您有两个独立的CRT副本,具有独立且不同的状态,因此您必须小心尝试跨越CRT边界.有两种方法可以解决两个CRT的问题.这里仅仅是少数:

  • 有两个单独的堆.您不能分配(显式地使用new,malloc等 - 或者使用strdup,strstreambuf :: str等隐式),然后将指针传递给要释放的CRT边界.
  • 您不能跨CRT边界传递FILE*或文件句柄,并期望"stdio低级IO"工作.
  • 您不能将语言环境设置为一个,并期望设置另一个语言环境.

从Visual C++ 4.0开始,如果生成的模块尝试组合CRT库的多个副本,链接器将发出警告(LNK4098).有关更多信息,请在LNK4098的帮助文件中搜索.

但我没有从VS2010链接器收到任何LNK4098错误消息.

Leptonica使用fopen(),rewind(),fclose()等文档归类为Stream I/O而不是"低级别IO",但那些传递了FILE ptrs.我想这就是微软在说"stdio低级IO"时的意思.

/ MD,/ MT,/ LD(使用运行时库)说:

传递给链接器的给定调用的所有模块必须使用相同的运行时库编译器选项(/ MD,/ MT,/ LD)进行编译.

并不是说所有模块都必须由相同版本的编译器编译.我对所有模块都使用/ MD(或/ MDd)一致且正确.

当使用DLL时,似乎DLL不仅必须使用相同的/ MD交换机,而且它们也必须由VS2010编译?

我的测试用例似乎表明与VS2008生成的静态库链接有效,但也许我很幸运?为什么链接到VS2008生成的静态库工作,而链接到VS2008生成的DLL不使用VS2010?

这是否意味着我需要运送单独的DLL供VS2008和VS2010用户使用?


那么新的Platform Toolset选项呢?VS2010用户可以将其更改为v900,即使他们没有VS2008吗?如果是这样,那么我可以告诉人们改变我的Leptonlib-1.67项目的设置.


最后,我在创建库时使用/ Z7开关./ Z7,/ Zi,/ ZI(调试信息格式)中的文档指出:

/ …

dll linker visual-studio-2010 visual-studio-2008 visual-c++

12
推荐指数
2
解决办法
1万
查看次数