【发布时间】:2018-08-27 14:28:37
【问题描述】:
我目前有一个 C++ 示例以这种方式调用 C++ DLL 函数:
typedef BOOL(__stdcall *f_funci)(const char*, char*);
HINSTANCE hGetProcIDDLL = LoadLibrary(L"myDLL.dll");
f_funci DoSmth= (f_funci)GetProcAddress(hGetProcIDDLL, "function");
std::string test = "The cake is a lie, it's actually a Brownie...";
char *out = new char[124];
DoSmth(&test[0], out);
以及DLL函数原型:
BOOL function(const char *in, char *out){}
问题是,当我调用这个 DLL 函数时,我在in[x](无论x 值是什么)处得到一个完全随机的结果(使用 Visual Studio 调试器)。
但是,如果我只是将此函数粘贴到我的 .cpp 中,in[x] 始终是我期望的结果。
我验证的内容:
- DLL 函数的调用约定是 stdcall,正如预期的那样。
- 示例和 DLL 都在以下上下文中 - 调试 - x64 -
我认为它可能来自什么但不知道足以确保回答是/否:
- “简单调用”和 GetProcAddress 之间的内存管理区别?
- 调试器问题(考虑到在 dll 调用情况下 out 值也是 false 会很奇怪)
- 其他?
如果有不清楚的地方,请考虑询问详情。
【问题讨论】:
-
只是好奇...将
std::string test更改为char的数组,看看行为是否有任何不同。 -
@ap-osd:您在评论中要求澄清,这应该已经足够了;我将您的(不是真正的)答案(实际上只是重新陈述了上述问题)标记为删除。特别是因为将
c_str()/data()的结果传递给采用 C 字符串 (const char *) 的函数是非常明确的;你的“答案”的那一部分是不正确的——即使没有那么明确,即使通过&test[0]应该不是问题。 -
@DevSolar - 我只是想强调一个事实,
std::string的内部存储器可以改变并且不可靠地保持它。请参阅参考资料 cplusplus.com/reference/string/string/c_str 和 en.cppreference.com/w/cpp/string/basic_string/c_str。无论如何,我会限制我对具体问题的回答。 -
@ap-osd:直接传递
const char *并不可靠。如果您正在查看单线程它是安全的,如果您正在查看多线程它是安全的,除非您开始修改字符串对象(就像您可以修改 C 字符串对象,例如释放或重新分配其内存)。这是一条红鲱鱼。 -
@DevSolar - 理论上这是公平的。但是我在跨 dll 传递
std::string时遇到了类似的问题。也许您可以更好地解释为什么会发生这种情况,我很乐意删除我的“不正确”答案。
标签: c++ c++11 memory loadlibrary