从DLL函数返回字符串

Max*_*xpm 10 c++ string dll visual-studio-2010

由于某种原因,从DLL函数返回一个字符串会在运行时崩溃我的程序并出现错误Unhandled exception at 0x775dfbae in Cranberry Library Tester.exe: Microsoft C++ exception: std::out_of_range at memory location 0x001ef604...

通过编译DLL代码.exe并在main函数中进行一些简单的测试,我已经验证了函数本身的问题.

与其他的返回类型(功能int,double等)正常工作.

  • 为什么会这样?
  • 有办法解决这种行为吗?

DLL的源代码:

// Library.h
#include <string>

std::string GetGreeting();
Run Code Online (Sandbox Code Playgroud)

.

// Library.cpp
#include "Library.h"

std::string GetGreeting()
{
    return "Hello, world!";
}
Run Code Online (Sandbox Code Playgroud)

测试人员的源代码:

// Tester.cpp
#include <iostream>
#include <Library.h>

int main()
{
    std::cout << GetGreeting()
}
Run Code Online (Sandbox Code Playgroud)

编辑:我正在使用VS2010.


结论

解决方法是确保使用具有相同选项相同编译器编译库和源,等等.

Bil*_*eal 6

这是因为您在一个DLL中分配内存(使用std :: string的构造函数),并在另一个DLL中释放它.你不能这样做,因为每个DLL通常设置它自己的堆.

  • 只是一个想法,会在完全位于DLL边界一侧的std :: strings上使用自定义分配器吗?这可能确保分配和释放所有内存都发生在同一个堆中 (2认同)
  • @bdk:那应该有用 - 当然它不再是`std :: string`了.(它将是`std :: basic_string <char,std :: char_traits <char>,MyAllocatorType>`) (2认同)

ima*_*boy 5

由于您的错误消息表明您正在使用Microsoft C++,因此我将提供MS特定的答案.

只要您使用SAME编译器编译EXE和DLL,并且两者都链接运行时的SAME版本DYNAMICALLY,那么您就可以了.例如,两者都使用"多线程DLL".

如果您静态链接运行时,或链接到运行时的不同版本,那么您就是SOL,原因是@Billy ONeal指出(内存将分配到一个堆中并在另一个堆中释放).