我写了/支持一个名为uCon的终端模拟器(http://www.umonfw.com/ucon).它全部基于"good-ole"Win32,完全是'C'.我最近被要求支持将uCon连接到COM端口并为RS232流量控制之外的目的设置DTR/RTS的能力.我知道在使用EscapeCommFunction()和/或SetCommState()调用CreateFile()之后我可以这样做; 但是,这些函数只能被调用AFTER CreateFile()返回打开端口的句柄.不幸的是,当CreateFile()打开端口时,它将DTR/RTS设置为默认状态,这可能(或可能不)与我希望保留DTR的状态不同.
例如,假设用户的板连接到PC的串行端口,DTR线用于将板放置在某种非标准状态.在DTR无效的情况下,电路板运行"正常",但偶尔使用DTR激活将硬件转换到其他状态.
在大多数情况下,我看到,CreateFile()使DTR处于活动状态,然后我对清除DTR的调用将其恢复为非活动状态; 然而,这是一个我需要避免的故障.我发现了一个名为GetDefaultCommConfig()和SetDefaultCommConfig()的函数集,但是无法使它们成功运行.所以,我的问题是......
有没有办法预先定义在调用CreateFile()时将在RS232控制线上建立的默认状态?有没有人成功使用过GetDefaultCommConfig()/ SetDefaultCommConfig()?
在我看来,这应该允许我预先建立在调用CreateFile()时使用的DTR的值...
int
EstablishDefaultDTR(char *comPortName, int dtr)
{
COMMCONFIG cc;
DWORD bsize = sizeof(COMMCONFIG);
if (GetDefaultCommConfig(comPortName,&cc,&bsize) == 0) {
ShowLastError("GetDefaultCommConfig()");
return(-1);
}
if (dtr)
cc.dcb.fDtrControl = DTR_CONTROL_ENABLE ;
else
cc.dcb.fDtrControl = DTR_CONTROL_DISABLE ;
if (SetDefaultCommConfig(comPortName,&cc,bsize) == 0) {
ShowLastError("SetDefaultCommConfig()");
return(-1);
}
}
但是,正如您可能已经猜到的那样,事实并非如此.有任何想法吗?
首先:这甚至可能吗?
我有一个第三方DLL连接一些硬件.它是用MFC编写的.我收到(来自dll供应商)一个示例Visual Studio 2010解决方案,该解决方案只有一个项目:一个MFC应用程序(.exe)调用有问题的第三方dll.它工作正常.
当我尝试使用我的dll中的第三方dll(这是普通的C++,没有MFC,没有.NET)时,我可以调用它的函数,但是有一个问题:示例MFC应用程序似乎按顺序"覆盖"MessageProc捕获第三方dll生成的某些消息.虽然dll有一个名为"RegisterFuncCallback"的函数并且我使用它,但我的回调永远不会被调用.
所以这就是问题:如何在不创建MFC应用程序的情况下捕获这些消息?(它甚至可能吗?)
我正在尝试实现一个队列,如果它是空的,则阻塞Pop操作,并在推送新元素时立即解除阻塞.我担心我可能会遇到一些竞争条件; 我试着看看其他一些实现,但我发现大多数是在.NET中完成的,而我发现的少数C++在很大程度上依赖于其他库类.
template <class Element>
class BlockingQueue{
DRA::CommonCpp::CCriticalSection m_csQueue;
DRA::CommonCpp::CEvent m_eElementPushed;
std::queue<Element> m_Queue;
public:
void Push( Element newElement ){
CGuard g( m_csQueue );
m_Queue.push( newElement );
m_eElementPushed.set();
}
Element Pop(){
{//RAII block
CGuard g( m_csQueue );
bool wait = m_Queue.empty();
}
if( wait )
m_eElementPushed.wait();
Element first;
{//RAII block
CGuard g( m_csQueue );
first = m_Queue.front();
m_Queue.pop();
}
return first;
}
};
Run Code Online (Sandbox Code Playgroud)
一些解释到期:
我担心使用Pop()时可能会出现一些奇怪的竞争情况.你们有什么感想?
更新:由于我正在使用Visual Studio 2010(.NET 4.0),我最终使用了C++运行时提供的unbounded_buffer类.当然,我使用Pointer to Implementation Idiom(Chesire Cat)将它包装在一个类中,以防我们决定更改实现或需要将此类移植到另一个环境
假设您有一个可以被多个线程访问的对象。临界区用于保护敏感区域。但是析构函数呢?即使我一进入析构函数就进入临界区,一旦调用了析构函数,对象是否已经失效了?
我的思路:假设我进入了析构函数,我必须等待临界区,因为其他线程仍在使用它。一旦他完成,我就可以完成破坏对象。这有意义吗?
我的程序在我可以重现的小场景中随机崩溃,但它发生在来自ntdll.dll的mlock.c(这是一个VC++运行时文件)中,我看不到堆栈跟踪.我知道它发生在我的一个线程函数中.
这是程序崩溃的mlock.c代码:
void __cdecl _unlock (
int locknum
)
{
/*
* leave the critical section.
*/
LeaveCriticalSection( _locktable[locknum].lock );
}
Run Code Online (Sandbox Code Playgroud)
错误是"指定的句柄无效".如果我看一下locknum,它的数量大于_locktable的大小,所以这是有道理的.
这似乎与关键部分的使用有关.我在我的线程中使用CRITICAL_SECTIONS,通过CCriticalSection包装器类及其相关的RAII保护器CGuard.两个定义在这里,以避免更多的混乱.
这是崩溃的线程函数:
unsigned int __stdcall CPlayBack::timerThread( void * pParams ) {
#ifdef _DEBUG
DRA::CommonCpp::SetThreadName( -1, "CPlayBack::timerThread" );
#endif
CPlayBack * pThis = static_cast<CPlayBack*>( pParams );
bool bContinue = true;
while( bContinue ) {
float m_fActualFrameRate = pThis->m_fFrameRate * pThis->m_fFrameRateMultiplier;
if( m_fActualFrameRate != 0 && pThis->m_bIsPlaying ) {
bContinue = ( ::WaitForSingleObject( pThis->m_hEndThreadEvent, static_cast<DWORD>( 1000.0f / m_fActualFrameRate …Run Code Online (Sandbox Code Playgroud) 我正在寻找可以写入支持集合的某种类型的迭代器/枚举器.据我了解,c#枚举器是只读的.
我有这个代码构建和运行完美:
boost::function<void(string)> bar = boost::bind(&Bar::BarHandler, this, _1);
//Somewhere else in Bar.cpp
void Bar::BarHandler( std::string message ){
//Do stuff
}
Run Code Online (Sandbox Code Playgroud)
当我兴高采烈地改变boost通过std在上面的代码中,我开始收到此错误(我的编译器的Visual Studio 2010 SP1的):
c:\program files\microsoft visual studio 10.0\vc\include\xxpmfcaller(42): error C2664:
'void (std::string)' : cannot convert parameter 1 from 'boost::arg<I>' to 'std::string'
1> with
1> [
1> I=1
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files\microsoft visual studio 10.0\vc\include\xxpmfcaller(52) : see reference to function …Run Code Online (Sandbox Code Playgroud) 我的 Winforms 应用程序在数据库中保存并恢复其 GUI 状态。除了拆分容器的 SplitterDistance 之外,一切正常。
该值已从数据库正确加载和设置,但是当我退出应用程序而不接触拆分器时,我希望它保存相同的值。但它保存了初始值-25像素。如果我多次打开和关闭应用程序,分离器距离每次都会减少 25 像素。
它不是一个自定义控件,只是一个普通的旧 .NET SplitContainer。仅以编程方式访问该控件以加载其初始 SplitterDistance 并在退出时保存它,仅此而已。
我该如何解决这个问题?
更新: spl 的FixedPanel属性最初设置为None。尝试将其设置为Panel1和Panel2;在这两种情况下,当我保存它时,SplitterDistance都会增加50 像素。
我使用Visual Studio 2010和我TestStack.White通过NuGet(我的版本0.10.3.118).
问题是,我的测试点击了一个触发超过默认5秒超时的操作的按钮.所以我的测试总是产生:
[Error] 'White.Core.Interceptors.CoreInterceptor' Error when invoking Click, on Button with parameters:
White.Core.UIItems.UIActionException : Window didn't respond, after waiting for 5000 ms
----> System.Exception : Timeout occured, after waiting for 5000 ms
Run Code Online (Sandbox Code Playgroud)
我阅读了White关于等待的文档,但是它会查看Configuration部分以了解如何设置我自己的超时值.那部分不存在.
更新:我尝试创建一个名为的文件TestStack.White.dll.config并将其放在TestStackWhite.dll与我的测试dll 相同的目录中.内容:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="White">
<section name="Core" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<White>
<Core>
<add key="WorkSessionLocation" value="." />
<add key="PopupTimeout" value="5000" />
<add key="SuggestionListTimeout" value="10000" />
<add key="BusyTimeout" value="10000" …Run Code Online (Sandbox Code Playgroud) 给定一个具有成员模板函数的类,如下所示:
template <typename t>
class complex
{
public:
complex(t r, t im);
template<typename u>
complex(const complex<u>&);
private:
//what would be the type of real and imaginary data members here.
}
Run Code Online (Sandbox Code Playgroud)
我对成员模板功能感到困惑,请提供一个示例,通过该示例,我可以清楚地了解成员模板功能的需求.
另外,告诉我在c ++中使用成员模板函数,我们使用成员模板函数的情况是什么?