【发布时间】:2014-04-12 07:26:13
【问题描述】:
我在通过引用 std::string 传递给 dll 中的函数时遇到问题。
这是函数调用:
CAFC AFCArchive;
std::string sSSS = std::string("data\\gtasa.afc");
AFCER_PRINT_RET(AFCArchive.OpenArchive(sSSS.c_str()));
//AFCER_PRINT_RET(AFCArchive.OpenArchive(sSSS));
//AFCER_PRINT_RET(AFCArchive.OpenArchive("data\\gtasa.afc"));
这是函数头:
#define AFCLIBDLL_API __declspec(dllimport)
AFCLIBDLL_API EAFCErrors CAFC::OpenArchive(std::string const &_sFileName);
我尝试通过调用函数逐步调试并查看函数内部的_sFileName值。
函数中的_sFileName 设置任何值(例如,t4gs..\n\t)。
我尝试检测任何堆损坏,但编译器说没有错误。
DLL 已在调试设置中编译。 .exe程序也在调试中编译。
怎么了??救命..!
附:我用的是 Visual Studio 2013。WinApp。
编辑
我已将 func 的标头更改为此代码:
AFCLIBDLL_API EAFCErrors CAFC::CreateArchive(char const *const _pArchiveName)
{
std::string _sArchiveName(_pArchiveName);
...
我真的不知道,如何修复这个错误......
关于堆:它分配在我们进程的虚拟内存中,对吧?在这种情况下,共享虚拟内存很常见。
【问题讨论】:
-
EXE 和 DLL 是否使用完全相同的编译器编译,使用完全相同的标志?否则,
std::string和其他 STL 类型的定义可能在 EXE 和 DLL 之间有所不同,这可能会导致问题。 -
我建议您保持 DLL 使用定义明确的 ABI 。通过 DLL 接口传递分配的内存是自找麻烦。例如,DLL 和调用应用程序可能没有使用同一个堆。
-
@MattMcNabb,如果他们不使用相同的堆,为什么会有问题?它们仍然共享相同的地址空间,对吧?
-
好吧,如果他添加到字符串并释放它的内存并分配新内存,另一个堆将无法释放,因为它不知道那个块,等等。
-
basic_string(const _Elem *_Ptr)- 它是在 .c_str() 之后调用的。_Ptr在进入函数的那一刻是对的:“data\\gtasa.afc”
标签: c++ string c++11 dll pass-by-reference