我正在使用Visual Studio 2010来构建我的DLL库 .
而且,使用Visual Studio 2005的其他程序员想要使用我的DLL库 . 他可以用我的dll编译,但是,在运行他的应用程序时,它只是崩溃与bad_alloc异常 . 我认为这是因为CRT版本不同 .
在构建我的DLL库时,我尝试了CRT(/ MD)的动态链接和CRT(/ MT)的静态链接,但都失败了 .
那么,我不能制作可以被较低版本的visual studio使用的DLL库吗?如果没有,我怎么能这样做?
最有可能的是,您正在使用在VC编译器实现版本之间发生更改的事物(如C容器或类型),并且在使用不同VC版本构建的DLL之间跨DLL边界传递这些内容可能会失败 .
您需要使用该特定编译器(VS 8.0的VC 8.0,2008的VC 9.0,2010的VC 10.0 ......)构建DLL,以便其他程序员使用它 . 那,或者他必须升级他的Visual Studio才能使用与你相同的版本 .
如果您的机器上安装了VS2005,则可以使用VS2010的新 Platform Toolset 功能来使用VS2005编译器 .
Platform Toolset
它在 Project Properties - > General - > Platform Toolset . VS100是vs2010,VS90是2008年和(我认为)VS80是你需要的(2005年......) .
Project Properties
General
AFAIK,试图使用不同的工具集构建DLL会更难(虽然可能,因为你没有链接它) .
干杯
据我所知,你必须只使用原始类型的dll接口 . 这是因为即使在相同的编译器内存布局更改只更改编译标志,请考虑通过更改编译器会发生什么 . 这可能导致大规模的不规范行为 .
并为您的函数接口使用以下格式:
extern "C" __declspec(dllexport) void doSomething(int input);
您只能导出抽象基类(包含至少一个纯虚函数)而没有数据成员以实现二进制兼容性,我想这是关于您的dll原型的问题 . 这里http://chadaustin.me/cppinterface.html就这个问题进行了很好的讨论 .
最简单的解决方案:给另一个程序员你的DLL的源代码,让他自己编译DLL对旧的CRT . 如果这不合适(因为你不想从你的手中提供源代码,或者你的DLL不能用VC 2005编译),要么你必须得到VC 2005编译器,要么得到另一个VC 2010 .
这是一个相当古老的问题,这是COM的原因之一 . 我建议你做以下事情 -
创建一个抽象基类和(又称接口)(比如说IExportedFunctionality),它公开当前导出的类(比如CExportedClass)提供的方法并具有虚拟析构函数 .
不要再导出CExportedClass了 .
从IExportedFunctionality派生CExportedClass并确保实现所有方法 .
从您的Dll中导出2个函数
a. GetExportedClass which returns a pointer to a new instance of CExportedClass upcast to IExportedFunctionality*. b. FreeExportedClass which accepts a IExportedFunctionality* and deletes it.
现在您需要做的就是为头文件提供IExportedFunctionality的声明 . 您甚至可以取消lib文件,因为您的用户可以使用LoadLibrary和GetProcAddress来调用GetExportedClass和FreeExportedClass .
注意:IExportedFunctionality应该有
只有纯虚函数 - 因为IExportedFunctionality是一个不实现的接口 .
纯虚析构函数 - 以便在IExportedFunctionality *上执行删除将转换为对CExportedClass的析构函数的调用
IExportedFunctionality中没有任何数据成员(因为user383522指出类的二进制布局可能因编译器和不同的字节对齐而异)
6 回答
最有可能的是,您正在使用在VC编译器实现版本之间发生更改的事物(如C容器或类型),并且在使用不同VC版本构建的DLL之间跨DLL边界传递这些内容可能会失败 .
您需要使用该特定编译器(VS 8.0的VC 8.0,2008的VC 9.0,2010的VC 10.0 ......)构建DLL,以便其他程序员使用它 . 那,或者他必须升级他的Visual Studio才能使用与你相同的版本 .
如果您的机器上安装了VS2005,则可以使用VS2010的新
Platform Toolset
功能来使用VS2005编译器 .它在
Project Properties
- >General
- >Platform Toolset
. VS100是vs2010,VS90是2008年和(我认为)VS80是你需要的(2005年......) .AFAIK,试图使用不同的工具集构建DLL会更难(虽然可能,因为你没有链接它) .
干杯
据我所知,你必须只使用原始类型的dll接口 . 这是因为即使在相同的编译器内存布局更改只更改编译标志,请考虑通过更改编译器会发生什么 . 这可能导致大规模的不规范行为 .
并为您的函数接口使用以下格式:
您只能导出抽象基类(包含至少一个纯虚函数)而没有数据成员以实现二进制兼容性,我想这是关于您的dll原型的问题 . 这里http://chadaustin.me/cppinterface.html就这个问题进行了很好的讨论 .
最简单的解决方案:给另一个程序员你的DLL的源代码,让他自己编译DLL对旧的CRT . 如果这不合适(因为你不想从你的手中提供源代码,或者你的DLL不能用VC 2005编译),要么你必须得到VC 2005编译器,要么得到另一个VC 2010 .
这是一个相当古老的问题,这是COM的原因之一 . 我建议你做以下事情 -
创建一个抽象基类和(又称接口)(比如说IExportedFunctionality),它公开当前导出的类(比如CExportedClass)提供的方法并具有虚拟析构函数 .
不要再导出CExportedClass了 .
从IExportedFunctionality派生CExportedClass并确保实现所有方法 .
从您的Dll中导出2个函数
现在您需要做的就是为头文件提供IExportedFunctionality的声明 . 您甚至可以取消lib文件,因为您的用户可以使用LoadLibrary和GetProcAddress来调用GetExportedClass和FreeExportedClass .
注意:IExportedFunctionality应该有
只有纯虚函数 - 因为IExportedFunctionality是一个不实现的接口 .
纯虚析构函数 - 以便在IExportedFunctionality *上执行删除将转换为对CExportedClass的析构函数的调用
IExportedFunctionality中没有任何数据成员(因为user383522指出类的二进制布局可能因编译器和不同的字节对齐而异)