【问题标题】:Difference between calling a "project" function and calling a DLL function调用“项目”函数和调用 DLL 函数之间的区别
【发布时间】: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_stren.cppreference.com/w/cpp/string/basic_string/c_str。无论如何,我会限制我对具体问题的回答。
  • @ap-osd:直接传递const char * 并不可靠。如果您正在查看单线程它安全的,如果您正在查看多线程它是安全的,除非您开始修改字符串对象(就像您可以修改 C 字符串对象,例如释放或重新分配其内存)。这是一条红鲱鱼。
  • @DevSolar - 理论上这是公平的。但是我在跨 dll 传递 std::string 时遇到了类似的问题。也许您可以更好地解释为什么会发生这种情况,我很乐意删除我的“不正确”答案。

标签: c++ c++11 memory loadlibrary


【解决方案1】:

嗯...我找到了解决方案,但我不知道它如何解决任何问题...

我实际上只是重新编译了 dll(使用相同的选项、相同的格式和内容),现在结果很好,并且运行良好。

如果有人对此有解释或线索,我会加入。

感谢所有回复和帮助!

【讨论】:

  • 这可能是任何事情。可能您正在针对过时的二进制文件进行测试。也许您确实将 DLL 设置为 __stdcall 但忘记重新编译。
  • 请注意,删除您的问题可能是个好主意,因为它的解决方式不太可能帮助其他访问者。
猜你喜欢
  • 2016-02-03
  • 1970-01-01
  • 2023-03-12
  • 2021-08-21
  • 1970-01-01
  • 2020-08-16
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多