|
the callback function doesn't take any parameters ? that sucks.
for this very reason, whenever we do a callback hook in one of our libraries, we specify our that the callback function must take at least one parameter large enough to hold a pointer. for example:
typedef BOOL (CALLBACK* IS40_SourceCloseFn)(const IS_CALLBACK_DATA uUserInfo);
you can pass a 32-bit value into the 'register callback' function and all the callback calls will pass that parameter back to you. so, you use an object pointer as the 32-bit value, the lib passes that value to the callback function, and you cast it back to the object type in the callback.
otherwise, you're stuck using global variables in the callback (and tricky synchronization schemes to make sure only one call is in there at a time).
|
|
|
|
|
The callback function and MyClass can't be modified. I've make it up so in order to focus the problem.
This is the code that you can't modify:
extern "C"<br />
{<br />
void register_callback(void (*callback) (void)); <br />
}
... if I also have a class like this:
class MyClass<br />
{<br />
int m_counter;<br />
public:<br />
MyClass() : m_counter(0) {}<br />
void OnEvent() <br />
{<br />
m_counter++;<br />
}<br />
}
Thanks
|
|
|
|
|
elmendavies wrote: extern "C"
{
void register_callback(void (*callback) (void));
}
Is this the signature of the real callback function? If it takes a context argument (generally void* ) then the solution is simple and well known.
Steve
|
|
|
|
|
I've make it up. It's not a real library function but it could be. Remember for example the signal function in UNIX and the definition of its callback:
http://www.hmug.org/man/3/signal.php
How to solve it?
|
|
|
|
|
If sizeof(int) is big enough to hold a pointer then something like the following will work.
extern "C"
{
void register_callback(void (*callback)(int), int arg);
}
class MyClass
{
int m_counter;
public: MyClass() : m_counter(0) {}
void OnEvent()
{
m_counter++;
}
}
void MyClassOnEventThunk(int arg)
{
MyClass *pInstance = reinterpret_cast<MyClass*>(arg);
pInstance->OnEvent(pInstance);
}
MyClass g_inst;
register_callback(&MyClassOnEventThunk, reinterpret_cast<int>(&g_inst));
If sizeof(int) is ***NOT*** big enough to hold a pointer you will have to maintain a mapping yourself.
Steve
|
|
|
|
|
my project is for grapic in 3 views, when closed program (visual c++ .net 2005, MFC) appear message error.
My project It is called stressinv.
The main window divided into 2 views within one creates two views. Grafico "OnDraw" at each hearing.
At the start of each hearing, uses "CSpritterWnd."
for more details please, written me to satw14@gmail.com.
sorry for my english, but speak spanish.
-------------------------------------------------------
Excepcion no controlada en 0x7821036a (mfc80d.dll) en stressinv.exe:
0xC0000005: Infraccion de acceso al leer la ubicacion Oxfeeefeee.
|
|
|
|
|
satw14 wrote: Excepcion no controlada...
An unhandled exception? So what are you doing when the application exits?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
//-MainFrm.cpp
Removed roles created by default and inclusions classes (include).
Here I try to create a view or two panels in the main view.
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
m_wndSplitter=NULL;
}
CMainFrame::~CMainFrame()
{
if (m_wndSplitter != NULL) delete m_wndSplitter;
}
//--Cleft and AreaView These classes are now aggregated
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* pContext)
{
m_wndSplitter=new CSplitterWnd();
if(!m_wndSplitter->CreateStatic(this,1,2))return false;
if(!m_wndSplitter->CreateView(0,0,RUNTIME_CLASS(CLeft),CSize(200,200),pContext))return false;
if(!m_wndSplitter->CreateView(0,1,RUNTIME_CLASS(AreaView),CSize(100,100),pContext))return false;
return TRUE;
}
// CMainFrame diagnostics
// when When I finished the program sends the mistake and put me here
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid(); //here
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
thanks David
-- modified at 18:24 Wednesday 17th October, 2007
|
|
|
|
|
satw14 wrote: m_wndSplitter=new CSplitterWnd();
Why are you not just using a stack-based member variable, rather than unnecessarily getting the memory manager involved?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
satw14 wrote: 0xC0000005: Infraccion de acceso al leer la ubicacion Oxfeeefeee.
Access Violation while trying to access a freed object? The 0xFEEEFEEE is often seen in things like data members of previously deallocated objects (debug).
Peace!
-=- James Please rate this message - let me know if I helped or not!<HR> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Hi
i hav converted an integer to a string using the following method,
CString str;
int i;
char TempBuffer[50];
_itoa(i,TempBuffer,10)
str=TempBuffer;
Now how can i convert a Float to a string .
any can please tell mi the solution(easy if the soln is similar to the above)
thanks
|
|
|
|
|
itoa is only between int and char.
if you want float or double try dtostr / strtod
And still better, if you are using CString, then use CString::Format
CString szValue = "";
szValue.Format (_T("%f"), doubleVariable);
This works with hexadecimal, int, binary... take a look in documentation.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
|
|
|
|
|
CString t;
t.Format("%f", floatVal);
|
|
|
|
|
the result from google search "c++ float to string" give this example...
int main()<br />
{<br />
char* str = new char[30];<br />
float flt = 2.4567F;<br />
<br />
sprintf(str, "%.4g", flt ); <br />
<br />
cout<<str<<endl;<br />
return 0;<br />
}
[Insert Witty Sig Here]
|
|
|
|
|
Please tell us the site where you got that from so that it can be blacklisted! Or at least the original author so other developers here can watch out for their name on a resume...
It is stupid enough to use new to allocate 30 bytes that are never used beyond the scope of allocation. It is also pretty dumb not to delete[] them. It is beyond my understanding why someone would make such code public. I mean, come on, at least show stuff like this to your friends first...
Oh, and the %g specifier is technically for double s, not float s. And mixes C and C++ style output (could format using the stream), etc...
Peace!
-=- James Please rate this message - let me know if I helped or not!<HR> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
|
You just as easily could have taken Google's second or third result and been much better off.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
VonHagNDaz wrote: [Insert Witty Sig Here]
waiting for something to insert [ ]
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
Besides all those Old-School C-Ways of converting,
there is the std::stringstream:
#include <strstream>
#include <iostream>
const double pi = 3.14;
std::string piString;
int main(int argc, char * argv[])
{
std::stringstream stream;
stream << pi;
stream >> piString;
std::cout << piString;
return system("pause");
}
Also, boost::lexical_cast[^] comes to mind.
Though I speak with the tongues of men and of angels, and have not money, I am become as a sounding brass, or a tinkling cymbal. George Orwell, "Keep the Aspidistra Flying", Opening words
|
|
|
|
|
saravananmechanical wrote: char TempBuffer[50];
Why are you using an intermediary variable? Convert i directly into str .
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi
I am trying create a remote thread using ::CreateRemoteThread API. I am able to open the remote process (with PROCESS_ALL_ACCESS), and allocate the memory and write the function code successfully. But, when i try to create remote thread, the remote process is crashing. Pls give some points, where it may go wrong?
|
|
|
|
|
ramana.g wrote: Pls give some points, where it may go wrong?
I have no experience with that API, but here is something they hid in the documentation:
Note that CreateRemoteThread may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread's process.
|
|
|
|
|
In other words they do no checking whatsoever on the start address parameter. When the remote thread starts the infrastructure will use a CALL instruction to call the supplied start address, and if you're lucky the processor will generate a page fault hardware exception straight away. The OS will turn that into an access violation exception since there's no suitable page mapping, it'll go looking for an exception handler, not find one, and call the process's unhandled exception filter. Typically that will kill the process.
If unlucky your address will point to some data and it'll run for a while before it encounters a bit pattern not matching a valid instruction, or the data being interpreted as code tries to touch invalid memory, or it trashes some other pointer in the real program code which causes a crash.
It's very difficult to examine a pointer to determine whether it really points to valid code, simply because the range of valid instructions is so vast. A human might be able to spot that the sequence of instructions doesn't make sense and deduce that it's really data, but building in a complete heuristic engine to work that out is not worthwhile.
DoEvents : Generating unexpected recursion since 1991
|
|
|
|
|
Mike Dimmick wrote: and if you're lucky
Well if you don't apply the luck keyword properly what do you expect? Really I'm not sure what your point is. You expect to pass an invalid address as a function pointer and everything will work out just fine?
|
|
|
|
|
ramana.g wrote: the remote process is crashing
How? Where? You must provide details of the crash! We're no psychic!
Steve
|
|
|
|