|
what does that offer over a normal function call? besides increased unreadability...
|
|
|
|
|
|
Hi Guys,
I am using GetModuleFileName API in my program. It returns me the name of my executable. However, I see that under different environments, it give me output like
-- Win XP
output: test.exe
-- Win 7
output: TEST.EXE
not sure why the API gives me different outputs. Please help.
|
|
|
|
|
Here is an excerpt from the documentation for GetModuleFileName -
The string returned will use the same format that was specified when the module was loaded. Therefore, the path can be a long or short file name, and can use the prefix "\\?\".
So the output will depend on how your EXE was loaded.
|
|
|
|
|
"So the output will depend on how your EXE was loaded."
Can you please help in elaborating it more?
|
|
|
|
|
To add more context, we are using CreateProcess(...) API to launch the exe file. However, even though the code is same but GetModuleFileName returns me different output.
|
|
|
|
|
|
|
I went though it, but able to get the reason.
|
|
|
|
|
And you still have not explained what your problem is.
Use the best guess
|
|
|
|
|
I would like to know if this particular API has any known issues.
|
|
|
|
|
Then you should read the documentation and Google for other questions.
Use the best guess
|
|
|
|
|
hello;
in a matrix of size m * n which contains only '0 'and '1', I want to calculate the sequence of two elements in each row.
example:
If the first row of the matrix is: 0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0
the first row of the matrix result should be: 5 3 4 2 2
That is to say: five zero, followed by 3 one, followed by four zeros, etc. ....
and so on for each row
|
|
|
|
|
M77ATTAT wrote: I want to... Ok, so what do you have so far (even if pseudo code on paper)?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
You need two additional variables, representing the last number seen (or the initial state) and a count of the number times you've seen this number. Reset these before processing a row.
|
|
|
|
|
yes indeed. I just found the solution as follows:
int* printArray(int *input,int max)
{
int *res;res=(int*)malloc(max*sizeof(int));for(int i = 0; i<max; i++) {res[i]=0;}
int current_kind = -1;
int count = 0;int cp=0;
for(int i = 0; i<max; ++i) {
if (current_kind!=input[i])
{
if (count!=0) res[ cp]=count;
current_kind = input[i] ;
count = 1;cp++;
} else { count++; }
}
res[cp]=count;
return res;
}
after, just use this function to calculate the matrix row by row.
thanks for suggestion !
|
|
|
|
|
I am opening a COM port in a class constructor - no problem.
I can send some data at this point too - no problem.
BUT, if I try to send data from any other method in the class it appears to work ok (I get the expected ERROR_IO_PENDING), but subsequently my code suffers an unpredictable and undebuggable crash. Any ideas anyone (please ask for more info' if needed)...
Some code;
CSerialDevice::CSerialDevice(
CString& strDeviceId,
CString& strDeviceName,
CString& COMPort,
CString& BaudRate,
CString& Format,
ComWrapper_c<CConnection15> Db, GobList_t& rGobList,
CSerialIOInterface* pInterface )
: pOurInterface( pInterface ),
m_hCommPort( NULL )
{
AddDigitalItems( strDeviceName, strDeviceId, Db, rGobList );
AddAnalogueItems( strDeviceName, strDeviceId, Db, rGobList );
if ( !ConfigureSerialPort( COMPort, BaudRate, Format ) )
{
pOurInterface->AddErrorToStatus( "Failed to configure port for " + strDeviceName );
}
}
bool CSerialDevice::ConfigureSerialPort(
CString& strCOMPort,
CString& strBaudRate,
CString& strFormat )
{
m_hCommPort = CreateFile(
strCOMPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0 );
DCB dcb = {0};
dcb.DCBlength = sizeof(DCB);
if ( !GetCommState( m_hCommPort, &dcb ) )
{
return false;
}
dcb.BaudRate = atoi( strBaudRate );
dcb.ByteSize = atoi( strFormat.Left( 1 ) );
int parity = NOPARITY;
if ( strFormat.Mid( 1 ) == 'N' )
{
parity = NOPARITY;
}
else if ( strFormat.Mid( 1 ) == 'E' )
{
parity = EVENPARITY;
}
else if ( strFormat.Mid( 1 ) == 'O' )
{
parity = ODDPARITY;
}
dcb.Parity = parity;
int stopBits = atoi( strFormat.Right( 1 ) );
switch ( stopBits )
{
case 0 : stopBits = ONESTOPBIT; break;
case 2 : stopBits = TWOSTOPBITS; break;
default : stopBits = ONESTOPBIT; break;
}
dcb.StopBits = stopBits;
if ( !SetCommState( m_hCommPort, &dcb ) )
{
return false;
}
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if ( !SetCommTimeouts( m_hCommPort, &timeouts ) )
{
return false;
}
Sleep( 100 );
int loops = 40;
while ( loops-- )
{
OVERLAPPED ovlWrite = {0};
WriteFile( m_hCommPort, mTxBuf, 7, NULL, &ovlWrite ); Sleep( 100 );
}
return true;
}
void CSerialDevice::TransmitData( int bytesToSend )
{
OVERLAPPED ovlWrite = {0};
WriteFile( m_hCommPort, mTxBuf, bytesToSend, NULL, &ovlWrite );
}
|
|
|
|
|
CSerialDevice::TransmitData( int bytesToSend )
{
OVERLAPPED ovlWrite = {0};
WriteFile( m_hCommPort, mTxBuf, bytesToSend, NULL, &ovlWrite );
}
The OVERLAPPED structure ovlWrite is a local variable that goes out of scope when leaving the function. But when writing is finished later, the system tries to access it. To avoid this, make ovlWrite a member variable of your class or make it static.
|
|
|
|
|
Many thanks, Jochen, that was the solution! (I live and learn...).
|
|
|
|
|
I try to keep code that "does stuff" out of the constructor and limit that method to doing attribute assignments. If I am correct, if something barfs in the constructor you have no way of handling the mess gracefully and recovering. Isn't there some kind of create or init method that you can use?
David
|
|
|
|
|
Thank-you, David. That wasn't the solution (see Jochen's reply above), but yours was still good advice...
|
|
|
|
|
The guys have already given you good hints, I give you another one: Never call virtual methods from the constructor and destructor of your classes because at the time the constructor and destructor is executed the vtable is set the the vtable of the class whose ctor/dtor is being executed even if this object is the instance of a derived class that would have override for the called virtual methods. This leads to a lot of errors and this C++ glitch also implies that serious initialization in the ctor is discouraged.
|
|
|
|
|
pasztorpisti wrote: the vtable is set the the vtable of the class whose ctor/dtor is being executed even if this object is the instance of a derived class
If you're constructing the object, the compiler knows the correct type at the time of construction, so how is the vtable going to be wrong?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
EDIT: previously I stated this has something to do with the closed world asssumptions of the compiler but I'm not sure about that. This thing works this way: It has no point to call the virtual method of a derived class whose constructor hasn't yet been executed because that virtual method would have access to uninitiailized members. In java and C# such virtual call calls the derived virtual method in contrast to C++!!!! But there at least the derived class members are already zero initialized, still, that is also the source of evil bugs! I had the luck to fix one such bug in java. Then why doesn't the compiler tell me about direct/indirect virtual calls from my ctor/dtor??? Because it can't always do that and even in some cases where it could tell it doesn't do that, probably the compiler writers didn't want to waste time on that or maybe this is the intended behavior even if its useless and often the source of bugs.
The code of the constructor of each c++ class looks like the following (Derived1 inherits from Base, Derived2 inherits from Derived1:
Base::Base()
{
auto generated: vtable = Base::vtable
<your ctor code here>
}
Derived1::Derived1()
{
auto generated: call Base::Base
auto generated: vtable = Derived1::vtable
<your ctor code here>
}
Derived2::Derived2()
{
auto generated: call Derived1::Derived1
auto generated: vtable = Derived2::vtable
<your ctor code here>
}
The destructors:
Base::~Base()
{
auto generated: vtable = Base::vtable
<your dtor code here>
}
Derived1::~Derived1()
{
auto generated: vtable = Derived1::vtable
<your ctor code here>
auto generated: call Base::~Base
}
Derived2::~Derived2()
{
auto generated: vtable = Derived2::vtable
<your ctor code here>
auto generated: call Derived1::~Derived1
}
With the above info guess what will be printed by this example program:
class Base
{
public:
Base()
{
VirtualCall();
}
~Base()
{
VirtualCall();
}
virtual void VirtualCall()
{
printf("Base::VirtualCall()\n");
}
};
class Derived : public Base
{
public:
virtual void VirtualCall()
{
printf("Derived::VirtualCall()\n");
}
};
void TestFunc()
{
Derived* d = new Derived;
delete d;
}
You should never do complex initialization and deinitialization in your ctor/dtor because the virtual call may be hidden inside non-virtual function calls several call deep. Or worse, when you write the ctor/dtor code it works well but someone introduces a virtual call into a non-virtual method later and this makes your ctor/dtor buggy. For this reason all I do in the ctor is filling the member vars with default values and in the dtor I just release resources held by member vars.
Indirect virtual func call with the same result as the above buggy code:
class Base
{
public:
Base()
{
IndirectVirtualCallFromCtorDtor();
}
~Base()
{
IndirectVirtualCallFromCtorDtor();
}
void IndirectVirtualCallFromCtorDtor()
{
VirtualCall();
}
virtual void VirtualCall()
{
printf("Base::VirtualCall()\n");
}
};
class Derived : public Base
{
public:
virtual void VirtualCall()
{
printf("Derived::VirtualCall()\n");
}
};
void TestFunc()
{
Derived* d = new Derived;
delete d;
}
An even worse case that results in a "runtime error: pure virtual function call":
class Base;
static void HelperFunc(Base* b);
class Base
{
public:
Base()
{
HelperFunc(this);
}
~Base()
{
HelperFunc(this);
}
virtual void VirtualCall() = 0;
};
static void HelperFunc(Base* b)
{
b->VirtualCall();
}
class Derived : public Base
{
public:
virtual void VirtualCall()
{
printf("Derived::VirtualCall()\n");
}
};
void TestFunc()
{
Derived* d = new Derived;
delete d;
}
|
|
|
|
|
OK, now it makes sense. Thanks, I learned something valuable.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|