C++;Boost::asio x64异步_发送失败,错误为10014(WSAEFAULT) 我们有一个C++程序移植到VisualStudio 2017中的X64。该程序使用boost asio通过TCP连接发送数据。该代码在32位中运行良好。但当我为x64构建并运行它时,异步发送失败,出现错误10014(WSAEFAULT),我调试到boost asio代码中,罪魁祸首是对windows方法WSASend的调用(在boost\asio\detail\impl\win\u iocp\u socket\u service\u base.ipp中):

C++;Boost::asio x64异步_发送失败,错误为10014(WSAEFAULT) 我们有一个C++程序移植到VisualStudio 2017中的X64。该程序使用boost asio通过TCP连接发送数据。该代码在32位中运行良好。但当我为x64构建并运行它时,异步发送失败,出现错误10014(WSAEFAULT),我调试到boost asio代码中,罪魁祸首是对windows方法WSASend的调用(在boost\asio\detail\impl\win\u iocp\u socket\u service\u base.ipp中): ,c++,boost,boost-asio,C++,Boost,Boost Asio,这是我目前失败的相关代码(简化为排除其他可能的原因)。 此时连接设置成功,我尝试通过连接发送第一个数据: std::vector<unsigned char> testWriteBuffer(16,0); boost::asio::async_write(m_Socket, boost::asio::buffer(&testWriteBuffer[0], testWriteBuffer.size()),

这是我目前失败的相关代码(简化为排除其他可能的原因)。 此时连接设置成功,我尝试通过连接发送第一个数据:

std::vector<unsigned char> testWriteBuffer(16,0);
boost::asio::async_write(m_Socket,
              boost::asio::buffer(&testWriteBuffer[0], testWriteBuffer.size()),
                                   boost::bind(&CTIPCTCPConnection::IOHandleWrite, boost::static_pointer_cast<CTIPCTCPConnection>(shared_from_this()), NextMessage->IsLowPriority(),boost::asio::placeholders::error));
不确定这是否相关,这是编译器的命令行(我们使用相同的选项构建了boost库):


查看您发布的几行代码似乎有点糟糕的是,
std::vector testWriteBuffer(16,0)
很可能存在于堆栈上,因此在调用
async\u write
后会被销毁,但它应该一直存在,直到完成例程运行为止。正如您在的文档中所看到的

应用程序负责确保内存区域在I/O操作不再需要之前保持有效

更新

是的,WSABUF受到
/Zp1
的影响,请看这个简单的例子:

//#pragma pack(push, 1)
#include <Winsock2.h>

#include <cstdio>

int main(int argc, char** argv)
{
    WSABUF buffer;
    printf("size - %zu, offset of buf - %zu, offset of len - %zu", sizeof(buffer), offsetof(decltype(buffer), buf), offsetof(decltype(buffer), len));
    return 0;
}
/#pragma包(推送,1)
#包括
#包括
int main(int argc,字符**argv)
{
WSABUF缓冲区;
printf(“大小-%zu,buf-%zu的偏移量,长度-%zu的偏移量”,大小(缓冲区),偏移量(decltype(缓冲区),buf),偏移量(decltype(缓冲区),len));
返回0;
}
不带包装,尺寸为-16,偏移量为buf-8,偏移量为len-0,
在x64上,尺寸为-12,偏移量为buf-4,透镜偏移量为-0。您不能在没有
/Zp1
的情况下隔离boost i/o部分并编译boost吗?

显然,原因是/Zp1编译标志(结构成员对齐)。一旦我将其从项目及其所有依赖项中删除,它就可以正常工作了。删除此选项确实会打开一个全新的WORM wrt向后兼容性罐。

除非您能够创建一个有意义的方法来向我们展示,否则将很难以有意义的方式帮助您(除了猜测)。是的,这是真的。我这样做是为了简化代码(原始代码使用共享指针正确地实现了这一点)。但这并不重要,因为代码甚至在向量超出范围之前就失败了。@GertCorthout,是的,
/Zp1
影响
WSABUF
,您不能隔离i/o代码以编译boost而不使用它吗?谢谢您的评论。一些额外的搜索发现了这类错误报告给MS:我们将在序列化和发送的数据定义周围使用:#pragma pack(push,1)STRUCT defination#pragma pack(pop)。是的,这是在需要对齐的结构周围使用这些pragama的常见方法。我想说,在整个项目中使用
/Zp1
似乎很奇怪。我同意,这在15-20年前是一条快速而肮脏的捷径。像往常一样,这类事情迟早会加倍地折磨你。
/GS /W4 /Zc:wchar_t /I"..\..\..\Export\Include" /I"..\Include" /I"..\..\Include" /I"..\..\..\Include" /I"..\..\..\Ref\Include" /ZI /Gm- /Od /sdl- /Fd"C:\Workspaces\grpMiddleware\gc_AsioCom_x64\AsioCommunication\Test\Vc150\Debug_x64\\Test.pdb" /Zc:inline /fp:precise /Zp1 /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_WIN32_WINNT=0X603" /D "WINVER=0X603" /D "_MBCS" /D "_CRT_SECURE_NO_WARNINGS" /D "_TOKHEIM_FUELPOS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /Fa"C:\Workspaces\grpMiddleware\gc_AsioCom_x64\AsioCommunication\Test\Vc150\Debug_x64\\" /EHsc /nologo /Fo"C:\Workspaces\grpMiddleware\gc_AsioCom_x64\AsioCommunication\Test\Vc150\Debug_x64\\" /Fp"C:\Workspaces\grpMiddleware\gc_AsioCom_x64\AsioCommunication\Test\Vc150\Debug_x64\\Testd.pch" /diagnostics:classic 
//#pragma pack(push, 1)
#include <Winsock2.h>

#include <cstdio>

int main(int argc, char** argv)
{
    WSABUF buffer;
    printf("size - %zu, offset of buf - %zu, offset of len - %zu", sizeof(buffer), offsetof(decltype(buffer), buf), offsetof(decltype(buffer), len));
    return 0;
}