Test on "GetFunctionPointerForDelegate"

G

Guest

Hi guys,

this is a small test to understand the Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

..h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

..cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

..css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp = Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the event
"event HookProc done" is added, So the function pointer delegate is passed to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and Do_Event:
in the unmanaged dll start a small loop where each 1 second is call my
managed delegate, this work fine !! I can see every second catching count
increasing, but the form class is freezed. If I call each event a Refresh() I
can see a refreshing but buttons or any other object doesn't respond at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

Not certain I like your architecture as it's tough to read and will be a
nightmare to maintain, especially on the unmanaged side, but that's another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your process'
primary UI thread, the entire UI will appear to freeze. You're getting
quantum from the scheduler only duing the time it's incrementing your
counter and setting the event (which is why you see the updates for that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or callee.

-Chris


tiziano fabbri said:
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp = Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the event
"event HookProc done" is added, So the function pointer delegate is passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and Do_Event:
in the unmanaged dll start a small loop where each 1 second is call my
managed delegate, this work fine !! I can see every second catching count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't respond at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll send the
result.
Regarding the architecture I agree with you, but the test is to understand
if I can use RTOS feature in netcf also: C# increase my production but I need
to work on the hardware and some function RTOS so I'm finding an aggreement
where is possible.

thanks, fabbrit

Not certain I like your architecture as it's tough to read and will be a
nightmare to maintain, especially on the unmanaged side, but that's another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your process'
primary UI thread, the entire UI will appear to freeze. You're getting
quantum from the scheduler only duing the time it's incrementing your
counter and setting the event (which is why you see the updates for that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or callee.

-Chris


tiziano fabbri said:
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp = Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the event
"event HookProc done" is added, So the function pointer delegate is passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and Do_Event:
in the unmanaged dll start a small loop where each 1 second is call my
managed delegate, this work fine !! I can see every second catching count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't respond at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

Hi ctacke,

I'm growing up my test. I fixed the problem that did you let me see: I'm
trying to use a version with thread and another one without it. The second
one is working well, but is not the best for my necessities. First soluction
is following wrote:

c++
"
PROVEEVENTI_API void Do_Event(HANDLE retFunct, HANDLE retEvent)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
hThEvent = CreateThread(NULL, 0, thEvent, (LPVOID) retFunct,
CREATE_SUSPENDED, NULL);
if(hThEvent != INVALID_HANDLE_VALUE)
{
eThEvent = CreateEvent(NULL, false, false, NULL);
if(eThEvent != INVALID_HANDLE_VALUE)
{
//CeSetThreadPriority(hThEvent, 100);
//CeSetThreadQuantum(hThEvent, 0);
ResumeThread(hThEvent);
}
else
hThEvent = INVALID_HANDLE_VALUE;
}
}
}

DWORD thEvent (LPVOID lpVoid)
{
void (*pfnCallback) (void);

pfnCallback = (void (__cdecl *) (void)) lpVoid;

while(!bExit)
{
Sleep(500);
(*pfnCallback)();
}
SetEvent(eThEvent);
return 0;
}
"

these two functions are the core of my test, but it doesn't work: In debug
under VS2005 the framework cash and say to me if I want sent to Microsoft the
logging error message, else if run the .exe from the device no effects.

What do you think [everybody] ??
thanks, fabbrit

tiziano fabbri said:
Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll send the
result.
Regarding the architecture I agree with you, but the test is to understand
if I can use RTOS feature in netcf also: C# increase my production but I need
to work on the hardware and some function RTOS so I'm finding an aggreement
where is possible.

thanks, fabbrit

Not certain I like your architecture as it's tough to read and will be a
nightmare to maintain, especially on the unmanaged side, but that's another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your process'
primary UI thread, the entire UI will appear to freeze. You're getting
quantum from the scheduler only duing the time it's incrementing your
counter and setting the event (which is why you see the updates for that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or callee.

-Chris


tiziano fabbri said:
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp = Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the event
"event HookProc done" is added, So the function pointer delegate is passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and Do_Event:
in the unmanaged dll start a small loop where each 1 second is call my
managed delegate, this work fine !! I can see every second catching count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't respond at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

What line is causing the exception?

-Chris


tiziano fabbri said:
Hi ctacke,

I'm growing up my test. I fixed the problem that did you let me see: I'm
trying to use a version with thread and another one without it. The second
one is working well, but is not the best for my necessities. First
soluction
is following wrote:

c++
"
PROVEEVENTI_API void Do_Event(HANDLE retFunct, HANDLE retEvent)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
hThEvent = CreateThread(NULL, 0, thEvent, (LPVOID) retFunct,
CREATE_SUSPENDED, NULL);
if(hThEvent != INVALID_HANDLE_VALUE)
{
eThEvent = CreateEvent(NULL, false, false, NULL);
if(eThEvent != INVALID_HANDLE_VALUE)
{
//CeSetThreadPriority(hThEvent, 100);
//CeSetThreadQuantum(hThEvent, 0);
ResumeThread(hThEvent);
}
else
hThEvent = INVALID_HANDLE_VALUE;
}
}
}

DWORD thEvent (LPVOID lpVoid)
{
void (*pfnCallback) (void);

pfnCallback = (void (__cdecl *) (void)) lpVoid;

while(!bExit)
{
Sleep(500);
(*pfnCallback)();
}
SetEvent(eThEvent);
return 0;
}
"

these two functions are the core of my test, but it doesn't work: In debug
under VS2005 the framework cash and say to me if I want sent to Microsoft
the
logging error message, else if run the .exe from the device no effects.

What do you think [everybody] ??
thanks, fabbrit

tiziano fabbri said:
Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll send
the
result.
Regarding the architecture I agree with you, but the test is to
understand
if I can use RTOS feature in netcf also: C# increase my production but I
need
to work on the hardware and some function RTOS so I'm finding an
aggreement
where is possible.

thanks, fabbrit

Not certain I like your architecture as it's tough to read and will be
a
nightmare to maintain, especially on the unmanaged side, but that's
another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls
Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your
process'
primary UI thread, the entire UI will appear to freeze. You're getting
quantum from the scheduler only duing the time it's incrementing your
counter and setting the event (which is why you see the updates for
that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or callee.

-Chris


message
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp =
Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the
event
"event HookProc done" is added, So the function pointer delegate is
passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and
Do_Event:
in the unmanaged dll start a small loop where each 1 second is call
my
managed delegate, this work fine !! I can see every second catching
count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't respond
at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

Hi ctacke, I'm sorry for delay.

I dont't see exception in test program. VS2005 close for it self in one
module, and I'm sending now the information to Microsoft, because the request
module pop up each time I try to debug these lines. If I run the same test in
the device I don't see effects, I have a catcher counter, in my form.
Maybe you can replay same situation on your VS2005.

Ciao fabbrit
What line is causing the exception?

-Chris


tiziano fabbri said:
Hi ctacke,

I'm growing up my test. I fixed the problem that did you let me see: I'm
trying to use a version with thread and another one without it. The second
one is working well, but is not the best for my necessities. First
soluction
is following wrote:

c++
"
PROVEEVENTI_API void Do_Event(HANDLE retFunct, HANDLE retEvent)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
hThEvent = CreateThread(NULL, 0, thEvent, (LPVOID) retFunct,
CREATE_SUSPENDED, NULL);
if(hThEvent != INVALID_HANDLE_VALUE)
{
eThEvent = CreateEvent(NULL, false, false, NULL);
if(eThEvent != INVALID_HANDLE_VALUE)
{
//CeSetThreadPriority(hThEvent, 100);
//CeSetThreadQuantum(hThEvent, 0);
ResumeThread(hThEvent);
}
else
hThEvent = INVALID_HANDLE_VALUE;
}
}
}

DWORD thEvent (LPVOID lpVoid)
{
void (*pfnCallback) (void);

pfnCallback = (void (__cdecl *) (void)) lpVoid;

while(!bExit)
{
Sleep(500);
(*pfnCallback)();
}
SetEvent(eThEvent);
return 0;
}
"

these two functions are the core of my test, but it doesn't work: In debug
under VS2005 the framework cash and say to me if I want sent to Microsoft
the
logging error message, else if run the .exe from the device no effects.

What do you think [everybody] ??
thanks, fabbrit

tiziano fabbri said:
Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll send
the
result.
Regarding the architecture I agree with you, but the test is to
understand
if I can use RTOS feature in netcf also: C# increase my production but I
need
to work on the hardware and some function RTOS so I'm finding an
aggreement
where is possible.

thanks, fabbrit

:

Not certain I like your architecture as it's tough to read and will be
a
nightmare to maintain, especially on the unmanaged side, but that's
another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls
Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your
process'
primary UI thread, the entire UI will appear to freeze. You're getting
quantum from the scheduler only duing the time it's incrementing your
counter and setting the event (which is why you see the updates for
that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or callee.

-Chris


message
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp =
Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the
event
"event HookProc done" is added, So the function pointer delegate is
passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and
Do_Event:
in the unmanaged dll start a small loop where each 1 second is call
my
managed delegate, this work fine !! I can see every second catching
count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't respond
at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

The watson screen is popping up becasue of a native exception. Some line of
your code is casuing that to occur. Which one?

-Chris


tiziano fabbri said:
Hi ctacke, I'm sorry for delay.

I dont't see exception in test program. VS2005 close for it self in one
module, and I'm sending now the information to Microsoft, because the
request
module pop up each time I try to debug these lines. If I run the same test
in
the device I don't see effects, I have a catcher counter, in my form.
Maybe you can replay same situation on your VS2005.

Ciao fabbrit
What line is causing the exception?

-Chris


message
Hi ctacke,

I'm growing up my test. I fixed the problem that did you let me see:
I'm
trying to use a version with thread and another one without it. The
second
one is working well, but is not the best for my necessities. First
soluction
is following wrote:

c++
"
PROVEEVENTI_API void Do_Event(HANDLE retFunct, HANDLE retEvent)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
hThEvent = CreateThread(NULL, 0, thEvent, (LPVOID) retFunct,
CREATE_SUSPENDED, NULL);
if(hThEvent != INVALID_HANDLE_VALUE)
{
eThEvent = CreateEvent(NULL, false, false, NULL);
if(eThEvent != INVALID_HANDLE_VALUE)
{
//CeSetThreadPriority(hThEvent, 100);
//CeSetThreadQuantum(hThEvent, 0);
ResumeThread(hThEvent);
}
else
hThEvent = INVALID_HANDLE_VALUE;
}
}
}

DWORD thEvent (LPVOID lpVoid)
{
void (*pfnCallback) (void);

pfnCallback = (void (__cdecl *) (void)) lpVoid;

while(!bExit)
{
Sleep(500);
(*pfnCallback)();
}
SetEvent(eThEvent);
return 0;
}
"

these two functions are the core of my test, but it doesn't work: In
debug
under VS2005 the framework cash and say to me if I want sent to
Microsoft
the
logging error message, else if run the .exe from the device no effects.

What do you think [everybody] ??
thanks, fabbrit

:

Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll
send
the
result.
Regarding the architecture I agree with you, but the test is to
understand
if I can use RTOS feature in netcf also: C# increase my production but
I
need
to work on the hardware and some function RTOS so I'm finding an
aggreement
where is possible.

thanks, fabbrit

:

Not certain I like your architecture as it's tough to read and will
be
a
nightmare to maintain, especially on the unmanaged side, but that's
another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls
Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your
process'
primary UI thread, the entire UI will appear to freeze. You're
getting
quantum from the scheduler only duing the time it's incrementing
your
counter and setting the event (which is why you see the updates for
that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or
callee.

-Chris


message
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp =
Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the
event
"event HookProc done" is added, So the function pointer delegate
is
passed
to
unmanaged dll. This is work !!
Clicking a button I call the unmanaged function Reset_Exit and
Do_Event:
in the unmanaged dll start a small loop where each 1 second is
call
my
managed delegate, this work fine !! I can see every second
catching
count
increasing, but the form class is freezed. If I call each event a
Refresh() I
can see a refreshing but buttons or any other object doesn't
respond
at my
events, like mouse o keyboard.

please help me, thank you fabbrit
 
G

Guest

Hi ctacke

I'll try to debug line by line the program.

thanks, fabbrit

The watson screen is popping up becasue of a native exception. Some line of
your code is casuing that to occur. Which one?

-Chris


tiziano fabbri said:
Hi ctacke, I'm sorry for delay.

I dont't see exception in test program. VS2005 close for it self in one
module, and I'm sending now the information to Microsoft, because the
request
module pop up each time I try to debug these lines. If I run the same test
in
the device I don't see effects, I have a catcher counter, in my form.
Maybe you can replay same situation on your VS2005.

Ciao fabbrit
What line is causing the exception?

-Chris


message
Hi ctacke,

I'm growing up my test. I fixed the problem that did you let me see:
I'm
trying to use a version with thread and another one without it. The
second
one is working well, but is not the best for my necessities. First
soluction
is following wrote:

c++
"
PROVEEVENTI_API void Do_Event(HANDLE retFunct, HANDLE retEvent)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
hThEvent = CreateThread(NULL, 0, thEvent, (LPVOID) retFunct,
CREATE_SUSPENDED, NULL);
if(hThEvent != INVALID_HANDLE_VALUE)
{
eThEvent = CreateEvent(NULL, false, false, NULL);
if(eThEvent != INVALID_HANDLE_VALUE)
{
//CeSetThreadPriority(hThEvent, 100);
//CeSetThreadQuantum(hThEvent, 0);
ResumeThread(hThEvent);
}
else
hThEvent = INVALID_HANDLE_VALUE;
}
}
}

DWORD thEvent (LPVOID lpVoid)
{
void (*pfnCallback) (void);

pfnCallback = (void (__cdecl *) (void)) lpVoid;

while(!bExit)
{
Sleep(500);
(*pfnCallback)();
}
SetEvent(eThEvent);
return 0;
}
"

these two functions are the core of my test, but it doesn't work: In
debug
under VS2005 the framework cash and say to me if I want sent to
Microsoft
the
logging error message, else if run the .exe from the device no effects.

What do you think [everybody] ??
thanks, fabbrit

:

Hi <ctacke/>,
thank you for the answer. I think to have understand, maybe, and this
morning I suspect that I was to much concentrated on the instruction,
suspecting something wrong in it, without check my test code. I'll
send
the
result.
Regarding the architecture I agree with you, but the test is to
understand
if I can use RTOS feature in netcf also: C# increase my production but
I
need
to work on the hardware and some function RTOS so I'm finding an
aggreement
where is possible.

thanks, fabbrit

:

Not certain I like your architecture as it's tough to read and will
be
a
nightmare to maintain, especially on the unmanaged side, but that's
another
topic. What you're seeing is expected behavior. You call into the
unmanaged function at the call to Do_Event, that in turn calls
Sleep(1000),
which halts the current thread for 1 second.

Since this is running in the context of the caller, which is your
process'
primary UI thread, the entire UI will appear to freeze. You're
getting
quantum from the scheduler only duing the time it's incrementing
your
counter and setting the event (which is why you see the updates for
that)
and then going right back to sleep.

The fix: move it to a background thread in either the caller or
callee.

-Chris


message
Hi guys,

this is a small test to understand the
Marshal.GetFunctionPointerForDelegate
method.

Under unmanage I wrote this DLL:

.h
"// defined with this macro as being exported.
#ifdef PROVEEVENTI_EXPORTS
#define PROVEEVENTI_API __declspec(dllexport)
#else
#define PROVEEVENTI_API __declspec(dllimport)
#endif

extern "C"
{
PROVEEVENTI_API void Set_Evento(HANDLE );
PROVEEVENTI_API void Set_Exit();
PROVEEVENTI_API void Reset_Exit();
PROVEEVENTI_API void Do_Event(void);
}
"

.cpp
"
#include "stdafx.h"
#include "ProveEventi.h"
#include <windows.h>
#include <commctrl.h>

BOOL bExit = false;
HANDLE mRetFunct = INVALID_HANDLE_VALUE;
void (*pfnCallback) (void);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// This is an example of an exported variable
PROVEEVENTI_API void Set_Evento(HANDLE retFunct)
{
if(retFunct != INVALID_HANDLE_VALUE)
{
pfnCallback = (void (__cdecl *) (void)) retFunct;
}
}

PROVEEVENTI_API void Do_Event()
{
while(!bExit)
{
Sleep(1000);
(*pfnCallback)();
}
}

PROVEEVENTI_API void Set_Exit()
{
bExit = true;
}

PROVEEVENTI_API void Reset_Exit()
{
bExit = false;
}
"

On managed Code I wrote this Dll:

.css
"
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace ProveEventiCLR
{
class EVClass
{
#region PInvoke
[DllImport("ProveEventi.dll")]
private static extern void Set_Evento(IntPtr proc);

[DllImport("ProveEventi.dll")]
private static extern IntPtr Do_Event();

[DllImport("ProveEventi.dll")]
private static extern int Set_Exit();

[DllImport("ProveEventi.dll")]
private static extern int Reset_Exit();

[DllImport("coredll.dll")]
private static extern IntPtr GetModuleHandle(string mod);

#endregion
#region delegates
public delegate void HookProc();
public event HookProc done;
#endregion

private GCHandle gch;
private static HookProc hookProc;
private int catchingCount;
public int Count
{
get { return catchingCount++; }
}

public EVClass()
{
catchingCount = 0;
hookProc = new HookProc(EventCatcher);
gch = GCHandle.Alloc(hookProc, GCHandleType.Pinned);
IntPtr pp =
Marshal.GetFunctionPointerForDelegate(hookProc);
Set_Evento(pp);
}

public void Run()
{
Reset_Exit();
Do_Event();
}

public void Stop()
{
Set_Exit();
}

private void EventCatcher()
{
catchingCount++;
done();
}
}
}
"

The small Dll in managed code is instanced inside a form and the
event
"event HookProc done" is added, So the function pointer delegate
is
passed
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top