reactor_logging_server会出现运行 error LNK2019

文章详细介绍了在使用ACE_wrappersexamplesC++NPv2的Reactor_Log_Server工程文件从vs2003迁移到vs2005时遇到LNK2019错误的解决方案。通过检查配置属性并确保aced.lib版本正确,成功解决了在vs2005中运行时的错误。


问题:

在ACE_wrappers\examples\C++NPv2\里面Reactor_Log_Server有两个工程文件

在vs2003中build C++NPv2_Reactor_Log_Server.vcproj,一切正常

但在vs2005中build C++NPv2_Reactor_Log_Server_vc8.vcproj,会出现运行 error LNK2019

在网上搜到过类似的错误,参考了一下

1配置属性--链接器--附加依赖项中加aced.lib,同时

2配置属性--c/c++--预处理器定义中加入ACE_BUILD_SVC_DLL

都不起作用

是不是在2005中还要设置一些选项呢?


vs2005中具体信息如下

1>------ 已启动生成: 项目: C++NPv2_Reactor_Log_Server, 配置: Debug Win32 ------

1>正在链接...

1>   正在创建库 .\reactor_logging_server.lib 和对象 .\reactor_logging_server.exp

1>Logging_Event_Handler_Ex.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall ACE_Time_Value::ACE_Time_Value(__int64,long)" ([email=__imp_??0ACE_Time_Value@@QAE@_JJ@Z]__imp_??0ACE_Time_Value@@QAE@_JJ@Z[/email]),该符号在函数 "public: virtual int __thiscall Logging_Event_Handler_Ex:pen(void)" ([email=?open@Logging_Event_Handler_Ex@@UAEHXZ]?open@Logging_Event_Handler_Ex@@UAEHXZ[/email]) 中被引用

1>Reactor_Logging_Server.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall ACE_Time_Value::ACE_Time_Value(__int64,long)" ([email=__imp_??0ACE_Time_Value@@QAE@_JJ@Z]__imp_??0ACE_Time_Value@@QAE@_JJ@Z[/email])

1>Logging_Event_Handler_Ex.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __int64 __thiscall ACE_Time_Value::sec(void)const " ([email=__imp_?sec@ACE_Time_Value@@QBE_JXZ]__imp_?sec@ACE_Time_Value@@QBE_JXZ[/email]),该符号在函数 "public: virtual int __thiscall Logging_Event_Handler_Ex:pen(void)" ([email=?open@Logging_Event_Handler_Ex@@UAEHXZ]?open@Logging_Event_Handler_Ex@@UAEHXZ[/email]) 中被引用

1>.\reactor_logging_server.exe : fatal error LNK1120: 2 个无法解析的外部命令

1>生成日志保存在“file://g:\tradeage\source\ACE_wrappers\examples\C++NPv2\Debug\C++NPv2_Reactor_Log_Server_vc8\I386\BuildLog.htm”

1>C++NPv2_Reactor_Log_Server - 4 个错误,0 个警告


解决方法:

的确是aced.lib的版本不对

以前在2003中运行

现在程序放到2005中运行,忘记重新产生aced.lib,呵呵


<think>我们正在讨论ACE框架中的run_reactor_event_loop方法。根据引用[2],run_reactor_event_loop是一个处理事件的循环,它会一直运行直到handle_events返回-1。因此,要结束这个循环,我们需要让handle_events返回-1。另外,引用[2]还提到,handle_events是由ACE_Reactor_Impl对象实现的,而ACE_Reactor_Impl有多种实现。所以,具体的停止方法可能依赖于所使用的Reactor实现。通常,停止事件循环的方法包括:1.在某个事件处理器(ACE_Event_Handler)中返回一个负值,这会导致handle_events返回-1。2.调用ACE_Reactor::end_reactor_event_loop()方法,这个方法会设置一个标志,通知事件循环退出。3.使用ACE_Reactor::notify()方法,通过Reactor的内部通知机制来触发一个退出事件。下面详细说明:方法一:在事件处理器中返回负值当事件处理器(例如读、写、异常等事件的处理函数)返回一个负值(例如-1)时,Reactor会移除该事件处理器并关闭句柄,同时handle_events函数会返回-1。而run_reactor_event_loop在handle_events返回-1时会退出循环。方法二:调用end_reactor_event_loop()ACE_Reactor类提供了end_reactor_event_loop()方法,该方法设置一个标志,使Reactor在下一次处理事件时退出循环。注意:这个方法不会立即中断事件循环,它只是设置一个标志,事件循环会在当前事件处理完成后检查这个标志并退出。方法三:使用通知机制(notify)可以通过ACE_Reactor::notify()方法发送一个通知事件。这个通知事件会被Reactor处理,并触发一个特殊的事件处理器(ACE_Event_Handler)。在这个事件处理器的handle_exception或handle_input等方法中,我们可以安排退出循环(例如调用end_reactor_event_loop()或者返回负值)。具体步骤示例(方法二):1.在需要停止事件循环的地方(例如另一个线程中),调用:reactor()->end_reactor_event_loop();2.为了确保Reactor能够及时退出,可能还需要唤醒Reactor(例如,如果Reactor当前阻塞在select调用中),这时可以同时调用:reactor()->wakeup();注意:wakeup()会使得Reactor从等待中返回,从而能够检查到结束标志。方法三的示例:我们可以创建一个专门用于停止的事件处理器,然后通过notify机制来激活它。步骤:1.创建一个事件处理器(例如StopHandler),在其handle_input(或handle_exception)方法中调用reactor->end_reactor_event_loop(),并返回-1(这样Reactor会移除这个处理器)。2.在需要停止循环时,调用reactor->notify(StopHandler的实例)。但是,通常更简单的是使用内建的notify机制,并设置一个全局的退出标志,然后在通知处理器中设置这个标志,并在后续检查中结束循环。需要注意的是,不同的Reactor实现(如Select_Reactor,TP_Reactor,WFMO_Reactor)在细节上可能有所不同,但上述方法在大多数情况下适用。根据引用[4],在Select_Reactor中,notify是在handle_events的最初被处理的,所以能够及时响应。因此,使用notify是一种可靠的方法。总结:推荐的做法是使用end_reactor_event_loop()结合wakeup(),或者使用notify()发送一个事件,在事件处理器中调用end_reactor_event_loop()。示例代码片段(方法二):在另一个线程中:reactor->end_reactor_event_loop();reactor->wakeup();这样,run_reactor_event_loop就会在下次循环时退出。注意:在多线程环境下,需要确保对Reactor的操作是线程安全的。另外,根据引用[3],Reactor模型的核心是事件处理器(ACE_Event_Handler),所以我们可以利用事件处理器来传递停止信号。因此,回答如下:</think>### 如何正确停止ACE框架中的`run_reactor_event_loop`方法 在ACE框架中,`run_reactor_event_loop`是事件处理的核心循环,其典型实现如下: ```cpp int ACE_Reactor::run_reactor_event_loop() { while (reactor_event_loop_done() == 0) { if (handle_events() == -1) break; // 关键退出点 } } ``` 要安全终止循环,需通过以下任一方法触发退出条件: #### 方法1:使`handle_events()`返回-1(推荐) 当事件处理器(`ACE_Event_Handler`)的以下方法返回`-1`时,会触发循环退出: ```cpp class MyHandler : public ACE_Event_Handler { public: int handle_input(ACE_HANDLE fd) override { if (exit_condition) return -1; // 触发循环终止 return 0; } }; ``` **原理**:`handle_events()`内部调用事件处理器时,若收到返回值`-1`,会终止循环[^2]。 #### 方法2:调用`end_reactor_event_loop()` ```cpp reactor->end_reactor_event_loop(); // 设置结束标志 reactor->wakeup(); // 唤醒阻塞的Reactor ``` **原理**: 1. `end_reactor_event_loop()`设置内部标志`reactor_event_loop_done_=1` 2. `wakeup()`强制`handle_events()`从多路复用(如`select()`)中返回 3. 下次循环检测到结束标志时退出[^2][^4] #### 方法3:通过通知机制(Notify) ```cpp // 发送退出通知 reactor->notify(new ExitCommandHandler()); class ExitCommandHandler : public ACE_Event_Handler { public: int handle_exception(ACE_HANDLE) override { reactor()->end_reactor_event_loop(); return -1; } }; ``` **优势**:跨线程安全,适用于异步终止[^4]。 --- ### 注意事项 1. **线程安全**:在MT环境下需使用`ACE_MT_SAFE`版本的Reactor[^4] 2. **及时唤醒**:调用`end_reactor_event_loop()`后必须配合`wakeup()`,否则可能阻塞直到超时 3. **资源清理**:退出前需注销所有事件处理器,避免资源泄漏 4. **实现差异**:`TP_Reactor`与`Select_Reactor`的唤醒机制存在实现差异[^4] > **最佳实践**:优先使用方法2(`end_reactor_event_loop() + wakeup()`),其行为最可预测且不依赖具体事件处理器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值