473,396 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

callbacks

Hi,

can anyone show me how to be able to pass the name of method to a dll
function which will call this method when something inside the dll calling
function happens.
Is this called a callback?

Are there any websites that show how to implement something like this
easily??
Nov 17 '05 #1
5 2558
Yes this is called a callback. You must just remember to "lock" your method
as "unsafe". If you do not so this the garbage collector might move your
methods' code around at some stage, and the DLL might call the "old" address
of your function ... which might not be the correct address ... causing some
problems, with difficult debugging!

"WAkthar" <wa*****@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Hi,

can anyone show me how to be able to pass the name of method to a dll
function which will call this method when something inside the dll calling
function happens.
Is this called a callback?

Are there any websites that show how to implement something like this
easily??

Nov 17 '05 #2

"Nico Gerber" <ng*****@telkomsa.net> wrote in message
news:O3**************@tk2msftngp13.phx.gbl...
Yes this is called a callback. You must just remember to "lock" your
method as "unsafe". If you do not so this the garbage collector might move
your methods' code around at some stage, and the DLL might call the "old"
address of your function ... which might not be the correct address ...
causing some problems, with difficult debugging!


This is not true, code never moves, the GC only moves objects in the GC
heap, code is not store in the GC heap!

Willy.
Nov 17 '05 #3
Guys guys...
The guy is looking for code examples...

I hope this will clear some stuff:

On your Cpp side:

You need to define a function pointer such as:
typedef void (__stdcall *LPFN_MANAGED_CALLBACK)(unsigned int x,unsigned
int y);

** don't forget the __stdcall

and a method to receive the EventHandler from the Managed side such as:
void MyCppMethod(LPFN_MANAGED_CALLBACK lpfnManagedCallback)
{
// To call the callback do:
lpfnManagedCallback(10 /*x value*/, 20 /*y value*/);
}
On the C# side:
1) you should define a delegate such as:
public delegate void PointEventHandler(uint x, uint y);

2) a member to hold the PointEventHandler so that it won't be
collected:
private PointEventHandler m_pointCallback;

3) a p/Invoke for the Cpp method:
[DllImport("CppDll.dll", CallingConvention=CallingConvention.StdCall)]
extern private static void CppMethod(PointEventHandler pointCB);

4) you need to create a method to handle the Cpp call:
private void CppCallbackHandler(uint x, uint y)
{
Console.WriteLine("Received a call from Cpp with X={0} & y={1}", x,
y);
}

5) you need to create the callback:
m_pointCallback = new PointEventHandler(CppCallbackHandler);

6) and now you can pass the callback to Cpp side:
CppMethod(m_pointCallback);

Cheers,
Eyal Safran

Nov 17 '05 #4
Thanks Eyal,

My scenario is a little different. There are two people involved in the
project.

I am writing the UI part and my collegue is writing a dll which will
communicate with teh serial port.

What we have is the ability for me to call functions that communicate with
the serial port. Now when certain events happen at the serial port, I need
to be notified.
To implement is I thought about using delegates as callbacks. The dll is
also written in C#.

When I create an object from the dll, I pass the function pointer (delegate)
to it. When an event happens on the serial port, this delegate is called and
I can update the UI.

Can you show how I can implement something like this please??

Thanks in advance!
"Eyal Safran" <ey**@mokedor.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Guys guys...
The guy is looking for code examples...

I hope this will clear some stuff:

On your Cpp side:

You need to define a function pointer such as:
typedef void (__stdcall *LPFN_MANAGED_CALLBACK)(unsigned int x,unsigned
int y);

** don't forget the __stdcall

and a method to receive the EventHandler from the Managed side such as:
void MyCppMethod(LPFN_MANAGED_CALLBACK lpfnManagedCallback)
{
// To call the callback do:
lpfnManagedCallback(10 /*x value*/, 20 /*y value*/);
}
On the C# side:
1) you should define a delegate such as:
public delegate void PointEventHandler(uint x, uint y);

2) a member to hold the PointEventHandler so that it won't be
collected:
private PointEventHandler m_pointCallback;

3) a p/Invoke for the Cpp method:
[DllImport("CppDll.dll", CallingConvention=CallingConvention.StdCall)]
extern private static void CppMethod(PointEventHandler pointCB);

4) you need to create a method to handle the Cpp call:
private void CppCallbackHandler(uint x, uint y)
{
Console.WriteLine("Received a call from Cpp with X={0} & y={1}", x,
y);
}

5) you need to create the callback:
m_pointCallback = new PointEventHandler(CppCallbackHandler);

6) and now you can pass the callback to Cpp side:
CppMethod(m_pointCallback);

Cheers,
Eyal Safran

Nov 17 '05 #5
Hi,
When I create an object from the dll, I pass the function pointer (delegate)
to it. When an event happens on the serial port, this delegate is called and
I can update the UI.

Can you show how I can implement something like this please??

Thanks in advance!


well it's you lucky day, (I hope thats what you ment).
I already wrapped unmanaged code to interact with the serial port:

[Flags]
public enum CommEvents
{
/// <summary>
/// No events
/// </summary>
EV_NONE = 0x0000,
/// <summary>
/// Any Character received
/// </summary>
EV_RXCHAR = 0x0001,
/// <summary>
/// Received certain character
/// </summary>
EV_RXFLAG = 0x0002,
/// <summary>
/// Transmit Queue Empty
/// </summary>
EV_TXEMPTY = 0x0004,
/// <summary>
/// CTS changed state
/// </summary>
EV_CTS = 0x0008,
/// <summary>
/// DSR changed state
/// </summary>
EV_DSR = 0x0010,
/// <summary>
/// RLSD changed state
/// </summary>
EV_RLSD = 0x0020,
/// <summary>
/// BREAK received
/// </summary>
EV_BREAK = 0x0040,
/// <summary>
/// Line status error occurred
/// </summary>
EV_ERR = 0x0080,
/// <summary>
/// Ring signal detected
/// </summary>
EV_RING = 0x0100,
/// <summary>
/// Printer error occurred
/// </summary>
EV_PERR = 0x0200,
/// <summary>
/// Receive buffer is 80 percent full
/// </summary>
EV_RX80FULL = 0x0400,
/// <summary>
/// Provider specific event 1
/// </summary>
EV_EVENT1 = 0x0800,
/// <summary>
/// Provider specific event 2
/// </summary>
EV_EVENT2 = 0x1000
}

protected CommEvents commEvents = CommEvents.EV_NONE;
private EventHandlerList events;

protected EventHandlerList Events
{
get
{
if (events == null)
{
lock(this)
{
if (events == null)
{
events = new EventHandlerList();
}
}
}
return events;
}
}

// Event objects
private static readonly object EventCharacterReceived;
private static readonly object EventCertainCharacterReceived;
private static readonly object EventTransmitQueueEmpty;
private static readonly object EventCTSStateChanged;
private static readonly object EventDSRStateChanged;
private static readonly object EventRLSDStateChanged;
private static readonly object EventBreakReceived;
private static readonly object EventLineStatusErrorOccurred;
private static readonly object EventRingSignalDetected;
private static readonly object EventPrintErrorOccurred;
private static readonly object EventReceiveBufferIs80PercentFull;
private static readonly object EventProviderSpecificEvent1;
private static readonly object EventProviderSpecificEvent2;

static Port() // static constructor
{
EventCharacterReceived = new object();
EventCertainCharacterReceived = new object();
EventTransmitQueueEmpty = new object();
EventCTSStateChanged = new object();
EventDSRStateChanged = new object();
EventRLSDStateChanged = new object();
EventBreakReceived = new object();
EventLineStatusErrorOccurred = new object();
EventRingSignalDetected = new object();
EventPrintErrorOccurred = new object();
EventReceiveBufferIs80PercentFull = new object();
EventProviderSpecificEvent1 = new object();
EventProviderSpecificEvent2 = new object();
}

// example to an event "Character Received" you register on:
public event EventHandler CharacterReceived // Any Character received
{
add
{
if (Events[EventCharacterReceived] == null)
{
commEvents |= CommEvents.EV_RXCHAR;
SetEvents();
}
Events.AddHandler(EventCharacterReceived, value);
}
remove
{
Events.RemoveHandler(EventCharacterReceived, value);
if (Events[EventCharacterReceived] == null)
{
commEvents &= ~CommEvents.EV_RXCHAR;
SetEvents();
}
}
}

protected void SetEvents()
{
if (commEvents == CommEvents.EV_NONE)
{
return;
}
if (Trace.debug())
{
Trace.debug("Setting {0} communication port events:\n{1}", PortName,
commEvents);
}
bool result = _SetCommMask(hPort, (int)commEvents);
if (result == false)
{
throw new CommunicationException("Failed to SetCommMask (set the
events)");
}
}

[DllImport("kernel32.dll", EntryPoint="SetCommMask",
SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
protected static extern bool _SetCommMask(
Int32 hFile,
int lpEvtMask);

[DllImport("kernel32.dll", EntryPoint="WaitCommEvent",
SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
protected static extern bool _WaitCommEvent(
Int32 hFile,
ref CommEvents Mask,
IntPtr lpOverlap);

public void WaitForEvents()
{
if (commEvents == CommEvents.EV_NONE)
{
throw new CommunicationException("No events have been registered.");
}
CommEvents eventsReceived = CommEvents.EV_NONE;
bool result = _WaitCommEvent(hPort, ref eventsReceived, IntPtr.Zero);
if (result == false)
{
throw new CommunicationException("Failed Waiting for comm events.");
}
// CharacterReceived
object[] args = new object[]{this, EventArgs.Empty};
EventHandler invoker = null;
if ((eventsReceived & CommEvents.EV_RXCHAR) == CommEvents.EV_RXCHAR)
{
invoker = (EventHandler)Events[Port.EventCharacterReceived];
if ( invoker != null)
{
invoker.DynamicInvoke(args);
}
}
}
Remark:
In this code, the user registers on the events, the first registration
on each event adds a flag to the member: "commEvents".
After all the clients unregistered from an the event, the flag is
removed from: "commEvents".

The collection of events is sent to the RS-232 port.

when the WaitForEvents is called, the thread is waiting for any of the
registered events to occur.
When they do, the C# event of the corresponding RS-232 event is
triggered.

Eyal.

Nov 17 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Melissa Wallis | last post by:
I have a class with 5 callbacks. Two of the callbacks work fine but the others don't. The main difference is that the callbacks that don't work are composed of a sequence of structs. I noticed a...
2
by: Mike C. Fletcher | last post by:
I'm looking at rewriting parts of Twisted and TwistedSNMP to eliminate __del__ methods (and the memory leaks they create). Looking at the docs for 2.3's weakref.ref, there's no mention of whether...
1
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion returns a pointer to a structure to its callback fucntion.The user should collect those...
0
by: ck388 | last post by:
For some reason when I enable the callback feature of the gridview I still get a page refresh, that is it seems like there is a postback that occurs, not a callback which is just supposed to update...
2
by: johny smith | last post by:
I cannot seem to figure out how to do instance based callbacks for some reason. I found one site on functors but I did not find it that helpful actually I just don't understand it. I have no...
5
by: Christopher Jastram | last post by:
I'm a self-taught programmer, so this might be a pretty dumb question. If it is, please point me in the right direction and I shall apologize profusely. I have a question regarding C++ and...
4
by: womanontheinside | last post by:
I have a library which was written in C, you call a function, it provides the result by a callback to specific function names. I am trying to wrap the calls to this inside a class, but this causes...
0
by: anilkoli | last post by:
I want clear cut idea about callbacks and also of delegates I have doughts about callbacks, I feel callbacks are used for 1. recursion 2. dynamically calling a perticular method out of many...
9
by: zholthran | last post by:
Hi folks, after reading several threads on this issue (-> subject) I fear that I got a problem that cannot easily be solved by the offered workarounds in an acceptable way, at least not with my...
13
by: noone | last post by:
consider the following problem: You have a C style library and API that uses callbacks to implement functionality. Examples of this are X11 API, OpenGL/GLUT...The List goes on. The power of...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.