当前位置:  开发笔记 > 编程语言 > 正文

使用具有不同编译器版本的C++ DLL

如何解决《使用具有不同编译器版本的C++DLL》经验,为你挑选了1个好方法。

这个问题与"如何跨VS版本制作一致的dll二进制文件"有关.

我们有使用VC6构建的应用程序和DLL以及使用VC9构建的新应用程序.VC9-app必须使用VC6编译的DLL,其中大部分用C语言编写,一个用C++编写.

由于名称修饰/修改问题,C++ lib存在问题.

用VC9编译所有内容目前不是一个选项,因为似乎有一些副作用.解决这些问题非常耗时.

我可以修改C ​​++库,但必须用VC6编译.

C++ lib本质上是另一个C库的OO包装器.VC9-app使用一些静态函数以及一些非静态函数.

虽然静态函数可以用类似的东西来处理

// Header file
class DLL_API Foo
{
    int init();
}

extern "C"
{
    int DLL_API Foo_init();
}

// Implementation file
int Foo_init()
{
    return Foo::init();
}

使用非静态方法并不容易.

据我了解,Chris Becke建议使用类似COM的接口对我没有帮助,因为接口成员名称仍然会被装饰,因此无法从使用不同编译器创建的二进制文件中访问.我在那儿吗?

唯一的解决方案是使用处理程序写一个C风格的DLL接口到对象还是我错过了什么?在这种情况下,我想,我可能会更少的努力直接使用包装的C库.



1> Roger Lipsco..:

使用使用与调用EXE不同的C++编译器编译的DLL时要考虑的最大问题是内存分配和对象生存期.

我假设您可以通过名称修改(和调用约定),如果您使用兼容的修改编译器(我认为VC6与VS2008大致兼容),或者如果您使用extern"C",这并不困难.

你遇到问题的地方是你从DLL中使用new(或malloc)分配一些东西,然后你将它返回给调用者.调用者delete(或free)将尝试从不同的堆中释放对象.这将是非常错误的.

你可以做一个COM风格的IFoo::Release东西,或者一MyDllFree()件事.这两个,因为他们回调到DLL,将使用正确的delete(或free())实现,因此他们将删除正确的对象.

或者,您可以确保使用LocalAlloc(例如),以便EXE和DLL使用相同的堆.


...只要你的智能指针回调DLL进行释放.默认情况下,将它包装在智能指针中只需调用*EXE的*delete,而不是DLL中的那个.
推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有