我编写了一个MFC C++应用程序,我的客户端进程MyCAsyncSocket::Connect在我的服务器进程中执行TCP .服务器进程用一个响应MyCAsyncSocket::OnAccept,然后Detach按照规定对套接字进行响应,创建一个Attach该套接字的线程,然后该套接字读取正在发送的数据.MSDN规定m_hSocket在之后设置为NULL Detach.
它工作正常,但只有一次.客户端第二次尝试访问Connect相同的套接字地址时,不会OnAccept发生通知.这是服务器代码:
void MyCAsyncSocket::OnAccept( int nErrorCode )
{
BOOL socketResult = FALSE;
CAsyncSocket syncSocket;
Accept( syncSocket );
AsyncSelect( FD_READ | FD_CLOSE );
SOCKET socket = syncSocket.Detach();
m_hSocket = NULL; // prescribed by msdn
... // go attach the socket in a worker thread, read the socket and do work
// try to re-establish listener.
...Create( // error: attempt 2: ASSERT(m_hSocket == INVALID_SOCKET)
endPoint.portNumber, // …Run Code Online (Sandbox Code Playgroud) 使用智能指针CComObject我通过调用静态方法创建一个COM对象CreateInstance.但是当我离开我的程序时,至少在VS13中,该对象仍在运行.这是我的代码:
CComObject< CMyAtlObject > * myAtlCOMObject = NULL;
HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject);
ASSERT(SUCCEEDED(hr));
Run Code Online (Sandbox Code Playgroud)
我期望在~CComObject()超出范围时调用该方法,而不会发生.
我尝试将上面的代码放在花括号中以强制新创建的对象超出范围.我试图调用FinalRelease上myAtlCOMObject,并成功地手动调用Release上myAtlCOMObject,但该方案仍然没有停止在VS13运行.
我错过了什么?
我想std::shared_ptr在调用其他窗口或线程时升级我的MFC生产代码以使用智能指针.这样的呼叫是SendMessage,PostMessage并且PostThreadMessage通过wparam和lparam分别是unsigned int和long.目前,我创建了一个类对象,一个新的对象,使调用传递一个指向该对象的指针,使用接收端的对象然后删除它.
由于shared_ptr我的其余代码工作得很好,我想至少探讨为什么我不能对Windows调用做同样的事情.
目前的电话:
auto myParams = new MyParams(value1, value2, value3);
PostThreadMessage(MSG_ID, 0, reinterpret_cast< LPARAM >( myParams );
ReceivingMethod::OnMsgId( WPARAM wParam, LPARAM lParam)
{
auto myParams = reinterpret_cast< MyParams * >( lParam );
... // use object
delete myParams;
}
Run Code Online (Sandbox Code Playgroud)
到类似C++ 11的智能指针调用:
std::shared_ptr< MyParams > myParams( new MyParams( value1, value2, value3 ) );
PostThreadMessage( MSG_ID, 0, ???myParams??? );
ReceivingMethod::OnMsgId( WPARAM wParam, LPARAM …Run Code Online (Sandbox Code Playgroud) 我的应用程序所做的一件事就是从套接字中侦听和接收有效负载.我永远不想阻止.在收到的每个有效负载上,我想创建一个对象并将其传递给工作线程并忘记它,直到稍后原型代码的工作方式.但是对于生产代码,我希望通过使用方便的异步方法来降低复杂性(我的应用程序很大).async采用了承诺的未来.为了实现这一点,我需要在Xxx类下面表示的非POD对象上创建一个promise.我没有看到任何方法(请参阅下面的示例代码中的错误).在这里使用异步是否合适?如果是这样,我如何构造一个比int更复杂的promise/future对象(我看到的所有代码示例都使用int或void):
#include <future>
class Xxx //non-POD object
{
int i;
public:
Xxx( int i ) : i( i ) {}
int GetSquare() { return i * i; }
};
int factorial( std::future< Xxx > f )
{
int res = 1;
auto xxx = f.get();
for( int i = xxx.GetSquare(); i > 1; i-- )
{
res *= i;
}
return res;
}
int _tmain( int argc, _TCHAR* argv[] )
{
Xxx xxx( 2 ); // 2 represents one payload …Run Code Online (Sandbox Code Playgroud) 我的应用包含大量ID.我想最终让其他人可以查看代码,但是不要让运行时反向工程师轻松查找容易知道的ID.此外,在开发期间,在日志文件中具有常量ID以便于调试是有帮助的.但是在运行时我想通过在Release编译期间生成这些ID来使它们随机.使用<random>lib的建议代码可以在GetRandomId1()下面看到.constexpr像在switch语句中那样在代码中使用它们.但是,我constexpr在提议的功能中使用时遇到了问题,因为<random>它不constexpr兼容.还有另一种在编译时生成随机数的方法吗?或者是在编译时生成随机数,以便在运行时用作常量来考虑constexpr?
#include <iostream>
#include <random>
// this is the code I would like to use to generate a random number at compile time
/*constexpr */int GetRandomId1()
{
std::random_device rd; // non-deterministic seed
std::mt19937 gen( rd() ); // with constexpr uncommented:
// error C3250: 'rd': declaration is not allowed in 'constexpr' function body
// error C3249: illegal statement or sub-expression for 'constexpr' function
// error C3250: 'gen': …Run Code Online (Sandbox Code Playgroud) 在重构我的项目以与模块一起使用之前,我编写了一个测试项目,ExImMod看看是否可以按照模块文档中的广告分离出声明和定义。对于我的项目,我需要将声明和定义保存在单独的翻译单元 (TU) 中,根据模块文档,这也是可能的。我不想使用模块分区。
不幸的是,我的测试ExImMod项目表明它们不能完全分离,至少对于 Visual Studio 2022 (std:c++latest) 编译器 (VS22) 来说是这样。
这是我的主要测试程序:
// ExImModMain.cpp
import FuncEnumNum;
import AStruct;
int main()
{
A a;
a.MemberFunc();
}
Run Code Online (Sandbox Code Playgroud)
A 的成员函数MemberFunc()在此声明:
// AStruct.ixx
// module; // global fragment moved to AMemberFunc.cppm (Nicol Bolas)
// #include <iostream>
export module AStruct; // primary interface module
export import FuncEnumNum; // export/imports functionalities declared in FuncEnumNum.ixx and defined in MyFunc.cppm
#include "AMemberFunc.hxx" // include header declaration
Run Code Online (Sandbox Code Playgroud)
其中包括“AMemberFunc.hxx”声明和定义:
// AMemberFunc.hxx
export struct A …Run Code Online (Sandbox Code Playgroud) 我想使用packaged_tasks将任务添加到容器中。我创建一个任务,将其绑定到一个数字,然后尝试将其放入双端队列。我在push_back上收到编译器错误C2280(VS2013)。这是代码:
void DoTask( int i )
{
std::cout << "int value: " << i << std::endl;
}
std::deque< std::packaged_task< void() > > task_q;
int _tmain(int argc, _TCHAR* argv[])
{
std::packaged_task< void() > t( std::bind( DoTask, 3 ) );
task_q.push_back( t ); // <-- C2280 error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我是从YouTube博前的讲座“ C ++线程#9:packaged_task”中获得此示例代码的。这是一些错误代码文本:“错误C2280:'std :: packaged_task :: packaged_task(const std :: packaged_task&)':尝试引用已删除的函数...请参见'std :: packaged_task :: packaged_task'的声明...同时编译类模板成员函数'void std :: allocator <_Ty> :: construct(_Ty *,const _Ty&)'1> with 1> [1> _Ty = std :: packaged_task“
这是经过两次更正的代码(移动任务和非无效返回值):
int …Run Code Online (Sandbox Code Playgroud) c++ ×5
c++11 ×2
mfc ×2
asynchronous ×1
atl ×1
c++-modules ×1
c++20 ×1
com ×1
constexpr ×1
future ×1
promise ×1
random ×1
sendmessage ×1
sockets ×1
tcplistener ×1
tuples ×1