gpt4 book ai didi

c++ - 从 C++/CLI 调用 DLL 函数时的 PInvokeStackImbalance

转载 作者:行者123 更新时间:2023-11-28 05:08:32 24 4
gpt4 key购买 nike

在处理 C++/CLI 项目以包装 native C++ DLL 时,我遇到了一个接受 std::string 的 native 函数。类似于以下内容:

class NativeApi
{
public:
ErrorCode readFile(std::string filename = "path.csv");
};

在我的托管包装器实现中,我分配了一个新的本地类实例并调用了这个函数:

ref class ManagedApi
{
private:
NativeApi *api;
public:
ManagedApi(): api(new NativeApi()) { }
void Read()
{
api->readFile("apath.csv") // or with nothing to use default value
}
}

当我运行它时,我收到 MDA PinvokeStackImbalance 提示此调用使堆栈不平衡。我很惊讶,因为我唯一一次获得此 MDA 是在调用约定不匹配时来自 C#。我从未见过这种情况发生在 C++/CLI 中,大概所有的匹配都是由编译器自动完成的。

有没有人见过这个?谷歌搜索是空的。我查看了 DLL 签名,它看起来像这样:

?readFile@NativeApi@@QAE?AW4ErrorCode@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z

这告诉我函数在那里,并将 basic_string 作为唯一参数,它应该匹配标准 std::string typedef。

不知道可能出了什么问题。我可以对不涉及字符串的 native API 进行其他调用。

最佳答案

您正在使用的 std::string 的定义与用于编译 native C++ DLL 的定义之间可能存在差异。即使定义相同, native DLL 也可能没有使用与您相同版本的 C 运行时,因此当您的 DLL 为 std::string 分配内存时, native DLL将尝试对其调用 delete(当字符串在 readFile 方法结束时被销毁时),并且对 delete 的调用将会继续与用于分配对象的堆不同!

如果你想让它工作,你必须使用与在 native DLL 上使用的编译器完全相同的版本。请注意,您将仅限于项目的发布版本,因为您没有使用调试运行时编译的 native DLL。

解决此问题的正确 方法是在跨 DLL 边界调用时使用原始类型(在本例中为 wchar_t*)。如果您可以请求更改 native DLL,我会这样做。如果只使用原始类型,那么使用不同的运行时就没有问题,一切都会按应有的方式工作。

关于c++ - 从 C++/CLI 调用 DLL 函数时的 PInvokeStackImbalance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44030710/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com