L
Lonewolf
Hi all,
I'm having difficulties passing data back to managed class from my
native class when the data is generated from within a native thread in
the native class itself. I will give the following runtime error,
" Attempting to call into managed code without transitioning out first.
Do not attempt to run managed code inside low-level native
extensibility points, such as the vectored exception handler, since
doing so can cause corruption and data loss."
Within this native class is a thread which updates some data, adn I
would like to pass these data back to the managed class via delegate
when it is updated. I created a delegate and function ptr for the
delegate to pass to the native class so that it can call the managed
class via the function ptr when the data gets updated. However, when
calling from within the thread, the above error occurs. How do I transit
out of the said "situation"? What should be the right way of doing this?
Below are some codes, greatly simplified for clarity to illustrate the
situation. Please enlighten me on the right way. The thread must be
present, as the data in actual fact is updated when soem events are set,
and I need to reflect this back to the managed class and store the
updated values within the managed class for easy retrieval from the
managed client using this mixed assembly. In my code, I have similar
delegate adn function ptr for native callback to managed class which
worked so I am puzzled why this can't. my guess is, it's called from the
thread itself and thus not allowed, as as .NET disallow updating of UI
from threads which don't own the UI. But I am lost how to overcome it.
CNativeClass
{
LPFNUPDATEVALUE m_pfn;
static uint ThreadProc(void* lpv)
{
BOOL bContinue=true;
CNativeClass* pParent=(CNativeClass*)lpv;
DWORD dwValue=0;
while (bContinue)
{
pParent->UpdateValue(dwValue++);
::Sleep(1000);
}
}
void UpdateValue(DWORD dw)
{
m_pfn(dw);
}
void Setfn(LPFNUPDATEVALUE pfn)
{
m_pfn=pfn;
}
};
the delegate is declared as
public delegate void UpdatevalueDelegate(DWORD);
and the function ptr is declared as
typedef void (*LPFNUPDATEVALUE)(DWORD);
public ref class CManagedClass
{
UpdatevalueDelegate^ m_Update;
CNativeClass* m_pNative;
GCHandle m_hGC;
public:
void InitNativeClass()
{
m_pNative=new CNativeClass();
m_Update=gcnew (this, &UpdateDel);
m_hGC = GCHandle::Alloc(m_Update);
IntPtr ip = Marshal::GetFunctionPointerForDelegate(m_Update);
pNative->Setfn(static_cast<LPFNUPDATEVALUE>(ip.ToPointer()));
}.
void UpdateDel(DWORD dw) <==this is the managed function called from
the native thread via delegate
{... }
};
I'm having difficulties passing data back to managed class from my
native class when the data is generated from within a native thread in
the native class itself. I will give the following runtime error,
" Attempting to call into managed code without transitioning out first.
Do not attempt to run managed code inside low-level native
extensibility points, such as the vectored exception handler, since
doing so can cause corruption and data loss."
Within this native class is a thread which updates some data, adn I
would like to pass these data back to the managed class via delegate
when it is updated. I created a delegate and function ptr for the
delegate to pass to the native class so that it can call the managed
class via the function ptr when the data gets updated. However, when
calling from within the thread, the above error occurs. How do I transit
out of the said "situation"? What should be the right way of doing this?
Below are some codes, greatly simplified for clarity to illustrate the
situation. Please enlighten me on the right way. The thread must be
present, as the data in actual fact is updated when soem events are set,
and I need to reflect this back to the managed class and store the
updated values within the managed class for easy retrieval from the
managed client using this mixed assembly. In my code, I have similar
delegate adn function ptr for native callback to managed class which
worked so I am puzzled why this can't. my guess is, it's called from the
thread itself and thus not allowed, as as .NET disallow updating of UI
from threads which don't own the UI. But I am lost how to overcome it.
CNativeClass
{
LPFNUPDATEVALUE m_pfn;
static uint ThreadProc(void* lpv)
{
BOOL bContinue=true;
CNativeClass* pParent=(CNativeClass*)lpv;
DWORD dwValue=0;
while (bContinue)
{
pParent->UpdateValue(dwValue++);
::Sleep(1000);
}
}
void UpdateValue(DWORD dw)
{
m_pfn(dw);
}
void Setfn(LPFNUPDATEVALUE pfn)
{
m_pfn=pfn;
}
};
the delegate is declared as
public delegate void UpdatevalueDelegate(DWORD);
and the function ptr is declared as
typedef void (*LPFNUPDATEVALUE)(DWORD);
public ref class CManagedClass
{
UpdatevalueDelegate^ m_Update;
CNativeClass* m_pNative;
GCHandle m_hGC;
public:
void InitNativeClass()
{
m_pNative=new CNativeClass();
m_Update=gcnew (this, &UpdateDel);
m_hGC = GCHandle::Alloc(m_Update);
IntPtr ip = Marshal::GetFunctionPointerForDelegate(m_Update);
pNative->Setfn(static_cast<LPFNUPDATEVALUE>(ip.ToPointer()));
}.
void UpdateDel(DWORD dw) <==this is the managed function called from
the native thread via delegate
{... }
};