CallbackOnCollectedDelegate was detected on Walther MFS100 Check Scanner - c#

i am trying to programming an interface for Walther Mfs100 Check scanner but after the scan i get "CallbackOnCollectedDelegate was detected" error. How can i fix this. I use .net 2.0 with c#
[DllImport("mflib.dll.stdcall")]
public static extern int mfScanFeeder(int mode, int font, int timeout);
retval = modMFS100.mfScanFeeder(0, 2,5000);

It isn't this particular API call that's the source of the problem. The API is too obscure and too poorly documented to give a straight answer, but look for an initialization style function that let's you set a callback. That callback is the cause of the exception. You must create a delegate object and store it in a field of your class. That way the garbage collector sees a reference to it and won't garbage collect it.
Thus, instead of:
void SetupScanner() {
mfInitialize(something, myCallback);
}
Do it like this:
SomeDelegateType callback;
void SetupScanner() {
callback = new SomeDelegateType(myCallback);
mfInitialize(something, callback);
}
Contact the vendor for support if this doesn't help.

Here is some info about this error:
http://social.msdn.microsoft.com/forums/en-US/Vsexpressvb/thread/665b876d-9070-41de-9a3a-d2093895d0c2
You can try to use static variable for your delegate, this will prevent the delegate from being garbage collected.

Related

How to prevent function pointer created in managed code, and passed to unmanaged code, from getting garbage collected

I am using a library called muParserNET in my application. muParserNET is a function parsing library, and my application is calling it multiple times from different threads.
muParserNET consists of a C++ (unmanaged) dll with a managed C# wrapper. In this wrapper, it passes the pointer to an error handling routine to the unmanaged library on initialisation.
i.e. within the Parser class we have this function:
/// <summary>
/// Error handler. It loads the ParserError exception.
/// </summary>
private void ErrorHandler()
{
IntPtr ptrMessage = MuParserLibrary.mupGetErrorMsg(this.parserHandler);
string message = Marshal.PtrToStringAnsi(ptrMessage);
IntPtr ptrToken = MuParserLibrary.mupGetErrorToken(this.parserHandler);
string token = Marshal.PtrToStringAnsi(ptrToken);
string expr = this.Expr;
ErrorCodes code = (ErrorCodes)MuParserLibrary.mupGetErrorCode(this.parserHandler);
int pos = MuParserLibrary.mupGetErrorPos(this.parserHandler);
// lança a exceção
throw new ParserError(message, expr, token, pos, code);
}
Here is the initialisation of the parser object, in managed code. it happens on the last line of this function:
public Parser()
{
// inicializa o parser
this.parserHandler = MuParserLibrary.mupCreate(0);
// inicializa o dicionário com as variáveis
this.vars = new Dictionary<string, ParserVariable>();
// inicializa as listas de delegates
this.identFunctionsCallbacks = new List<ParserCallback>();
this.funcCallbacks = new Dictionary<string, ParserCallback>();
this.infixOprtCallbacks = new Dictionary<string, ParserCallback>();
this.postfixOprtCallbacks = new Dictionary<string, ParserCallback>();
this.oprtCallbacks = new Dictionary<string, ParserCallback>();
// inicializa o delegate de factory
this.factoryCallback = new ParserCallback(new IntFactoryFunction(this.VarFactoryCallback));
// ajusta a função de tratamento de erros
MuParserLibrary.mupSetErrorHandler(this.parserHandler, this.ErrorHandler);
}
On running this code, sporadically, on calls to evaluate functions (so sometime after initialisation of the object) I get this error:
A callback was made on a garbage collected delegate of type 'muParserNET!muParserNET.ErrorFuncType::Invoke'
ErrorFuncType is the type of this.ErrorHandler passed above using MuParserLibrary.mupSetErrorHandler.
My understanding is that since the error handler function is not used after its pointer is passed to unmanaged code, it gets garbage collected. How can I prevent this from happening?
More information based on the first reply:
The parser object is created inside a calculation routine which may be running simultaneously on up to 8 separate threads, typically. The object is created and disposed of within the calculation routine. For this reason, I didn't want to create the parser object as static as it would limit me to only one thread using the parser at any one time.
Can't comment with < 50 reputation, but I don't have a clear answer, only hints.
So you are saying there can be multiple threads which all call "MuParserLibrary.mupSetErrorHandler"? That already seems wrong. Do the specs of the library declare mupSetErrorHandler, or in fact any part of the library as "thread safe"?
Imagine this scenario:
Thread A sets the error handler, starts work.
Thread B sets error handler, starts work. The current error handler in the library now has a reference to the error handler for thread-B.
Thread B finishes work earlier than A.
A produces an error.
Library still has a reference to error handler from B, which is now invalid.
From your example it's not clear whether B can stop earlier than A, but if there is another scenario possible getting you into such a state, that's what would happen.
I think you'd need a more global error handler that the library always uses. But if you have no way of tracking the source (thread) of the error, or the library is just not made for multi-threaded use, it won't be of much help.
If this is the typical "static class C# wrapper around native C DLL" library thing, I'm afraid that that's the case.
You'd need several objects of the library state (with its references to error handlers and such), too, i.e. one per thread. If that library can't do that, the way you are doing things now won't work.
I figured this out in the end.
I create two class variables: one for function handler, and one for a GChandle:
private ErrorFuncType ptrErrHandler;
private GCHandle gchErrorHandler;
Then use GCHandle to prevent the function pointer from being garbage collected before passing it to unmanaged code:
ptrErrHandler = this.ErrorHandler;
this.gchErrorHandler = GCHandle.Alloc(ptrErrHandler);
MuParserLibrary.mupSetErrorHandler(this.parserHandler, ptrErrHandler);
Finally in the class destructor you need to free the GCHandle to allow it to get garbage collected:
gchErrorHandler.Free();

Unreachable Code Warning in Static EventHandler callback

We have an interesting issue occurring that I wonder if anyone may be able to shed light on. We are currently seeing the warning: "Method never reaches end or 'return' statement" on an event handler delegate callback that is rather odd.
Consider the following code (you can ignore the SCB_ functions, they are not relevant to the question):
public static class NativeBridge
{
private static UnityEventQueue _eventQueue;
private static bool _initialized;
public static void Init()
{
if (_initialized)
{
return;
}
_initialized = true;
SCB_SDKInit();
_eventQueue = UnityEventQueue.Instance;
_eventQueue.AppExiting += EventQueue_AppExiting;
SCB_registerReceivedSistrCallback(SistrReceived);
}
//Lots of other irrelevant code
private static void EventQueue_AppExiting(object sender, EventArgs e)
{
SCB_registerReceivedSistrCallback(null);
_eventQueue.AppExiting -= EventQueue_AppExiting;
SCB_SDKFinal();
_initialized = false;
}
}
The warning is on EventQueue_AppExiting. Here is the odd part. If I comment out the unregistration, _eventQueue.AppExiting -= EventQueue_AppExiting, the warning disappears.
We have tried a variety of "solutions" for what seems like a bug in the unreachability pass of the compiler:
Make the static class, non-static and adjust accordingly
Make the event in UnityEngineQueue static, and adjust accordingly
Place the event un-registration at the end of the callback method
Comment out the calls to the void SCB_ functions to sanity check
Various other Spaghetti at the wall solutions
All of the above yielded no change in the compiler's behavior. Our best guess is that the compiler detects the unregistration and thinks that because the delegate is removed, that it cannot complete execution at runtime, even though I believe the stack would have to continue execution even after removal because the invocation had already begun.
It does not seem like this is having any adverse effect in the application's execution, however it is difficult to debug due to the nature of the event's invocation conditions (Application Exiting).
What could the complier be seeing and/or what are we potentially doing wrong?
P.S.
For a bit of context, the class is static because it acts as an extern bridge to various platform specific libraries with a similar API. But that fact has little to do with the question, just to quell the "EWWWW Static Class" sentiment.
I think it is a bug as reported on this link:
https://bugzilla.xamarin.com/show_bug.cgi?id=42819
and here
https://bugzilla.xamarin.com/show_bug.cgi?id=41798
They report as fixed in version 6.2.0.259

Icon.FromHandle: should I Dispose it, or call DestroyIcon?

I use Win32 SHGetFileInfo to get a handle to the icon belonging to a certain file. There are a lot of descriptions how to do this, also on stackoverflow, for instance: Get icons used by shell
After calling the function you have a struct with the handle to the Icon. Using the static method Icon.FromHandle I can convert it to an object of class System.Drawing.Icon. This class implements System.IDisposable. Proper usage would be like:
using (Icon icon = Icon.FromHandle(shFileInfo.hIcon))
{
// do what you need to do with the icon
}
Upon leaving the using statement the icon object is disposed.
MSDN warns in the description of Icon.FromHandle (click to view):
When using this method, you must dispose of the original icon by using the DestroyIcon method in the Win32 API to ensure that the resources are released.
And in Icon.Dispose (click to view)
Releases all resources used by this Icon.
Question:
Is it enough to Dispose() the object, or should I call both Dispose() and DestroyIcon, or maybe call DestroyIcon instead of Disposing the object?
The .NET Icon class is remarkably clumsy, taking care of this yourself is required. The MSDN article for SHFILEICON makes no bones about it, you must call DestroyIcon(). And so does the MSDN article for Icon.FromHandle(). The exact moment in time you call DestroyIcon matters a great deal as well, it must be delayed until some code either has made a copy of the icon or until you no longer need the icon and would normally call its Dispose() method.
Beware of the code snippet in the MSDN article, it shows a scenario where DestroyIcon() is called early. Okay in that specific case since it is assigned to the Form.Icon property. A corner case and surely not what you want to do.
The only really decent way to deal with this is to override the behavior of Icon.FromHandle() and force the object to take ownership of the native icon handle. So that it will automatically call DestroyIcon() when you dispose it. That requires a hack, the Icon constructor that lets you do this is internal. Reflection to the rescue, you can use the code from this post, note the GetConstructor() call. Start feeling good about it by writing a little unit test that does this a million times. If you hate it then write your own IDisposable wrapper so you can both dispose the icon and pinvoke DestroyIcon().
Addition by OP. There is an error in this answer. Because of all the comments it became harsh to see the forest through the trees. Hence I decided to edit this answer. (Sorry if I offended someone)
The .net source code is online: http://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Icon.cs,81a28d20524554ae
Take a look at Icon.FromHandle:
public static Icon FromHandle(IntPtr handle)
{
IntSecurity.ObjectFromWin32Handle.Demand();
return new Icon(handle);
}
internal Icon(IntPtr handle) : this(handle, false)
{
}
internal Icon(IntPtr handle, bool takeOwnership)
{
if (handle == IntPtr.Zero)
{
throw new ArgumentException(SR.GetString(SR.InvalidGDIHandle,
(typeof(Icon)).Name));
}
this.handle = handle;
this.ownHandle = takeOwnership;
}
Note that after Icon.FromHandle ownHandle is false.
Let's look at Dispose:
void Dispose(bool disposing)
{
if (handle != IntPtr.Zero)
{
DestroyHandle();
}
}
internal void DestroyHandle()
{
if (ownHandle)
{
SafeNativeMethods.DestroyIcon(new HandleRef(this, handle));
handle = IntPtr.Zero;
}
}
Conclusion: After Icon.FromHandle, the field ownHandle is false, and thus Dispose / FromHandle won't call DestroyIcon
Therefore: if you create an Icon using Icon.FromHandle you'll have to Dispose() the Icon as well as call DestroyIcon, just as the remarks section says
I have had NO END of grief in this area - I've been trying to animate a form's icon (and consequently the one in the task bar) without it leaking resources.
When I disposed of the icon (as suggested on MSDN) resources leaked, when I used "DestroyIcon" all subsequent updates failed. This code below shows everything in the correct order.
API Declaration:
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);
FINALLY the solution:
IntPtr iconHandle = dynamicBitmap.GetHicon();
Icon tempManagedRes = Icon.FromHandle(iconHandle);
this.Icon = (Icon)tempManagedRes.Clone();
tempManagedRes.Dispose();
DestroyIcon(iconHandle);
Also posted in this question:
Win32.DestroyIcon vs. Icon.Dispose

Implications of throwing exception in delegate of unmanaged callback

What are the implications or unperceived consequences of throwing an exception inside of a delegate that is used during an unmanaged callback? Here is my situation:
Unmanaged C:
int return_callback_val(int (*callback)(void))
{
return callback();
}
Managed C#:
[DllImport("MyDll.dll")]
static extern int return_callback_val(IntPtr callback);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int CallbackDelegate();
int Callback()
{
throw new Exception();
}
void Main()
{
CallbackDelegate delegate = new CallbackDelegate(Callback);
IntPtr callback = Marshal.GetFunctionPointerForDelegate(delegate);
int returnedVal = return_callback_val(callback);
}
The native code will bomb on the unhandled exception and the program terminates.
If you actually want to handle that exception then you need to use the custom __try/__catch keywords in the native code. Which is pretty useless, all the details of the managed exception are lost. The only distinguishing characteristic is the exception code, 0xe0434f4d. Since you cannot know exactly what went wrong, you cannot reliably restore the program state either. Better not catch it. Or better not throw it.
I think the correct way to say to a COM Object you have an exception is simply to return HRESULT.E_FAIL.
Could not test it right now, but I think that if the COM Object is in another process, all you will do is to kill your process and the COM Object may become unresponsive, waiting for your code to return from the callback function (since your process is dead already).

How do I pass arguments to a Thread in .Net

I have function along these lines:
public void view(string msg)
{
messagebox.show(msg);
}
.
.
I want to pass arguments to this it from a thread.. I'm using .Net 1.1. How can I do this?
For .NET 1.1 there is no direct way but to use an object having both the method and the state, in this example (modified from the MSDN sample), the ThreadState class is instanced and passed the desired state, then its method is called and made to use the passed state.
public class ThreadState {
private string msg;
// The constructor obtains the state information.
public ThreadState(string msg) {
this.msg = msg;
}
public void view() {
//Do something with msg
}
}
public class Example {
public static void Main() {
ThreadState ts = new ThreadState("Hello World!");
// Create a thread to execute the task, and then
// start the thread.
Thread t = new Thread(new ThreadStart(ts.view));
t.Start();
t.Join();
}
}
For .NET > 1.1 (original question didn't state version.)
You pass the argument in the Start method. You will receive an object which you need to cast back to the proper type.
Thread t = new Thread(view);
t.Start("Hello");
public void view(object msg)
{
string m = (string)msg;
//Use msg
}
Either that, or use a ParameterizedThreadStart delegate.
The ParamaterizedThreadStart delegate is not present in .NET 1.1 (2003) nor does thread.Start take an Object param in 1.1. However you could try something like:
dict[mythread.name] = myval; //dict is a class scoped variable.
mythread.Start();
There are various ways to do that. One is to use the ParameterizedThreadStart delegate, which allows passing a single parameter of type Object to the thread. Change your view method to accept Object, then cast Object to String inside the method.
Create a class, set your properties as arguments and run related function of the class.
Dim run = New Runner()
run.mile = 20
run.pace = "slow"
Thr.Start(run.Process())
Or you need to use a global scope variable. Unfortunately no other way for .NET 1.1
The first code snippet provided by Vinko is exactly what you need under .NET 1.x as the original Threading namespace offered no in-built mechanism for parameterizing _beginthread.
Thus, you create a state class which contains the data you need, as well as the method which will be used for the delegate in the "new Thread()" statement, as Vinko has shown.
I was about to tap out a sample, and then I saw his sample code. If it's "not working" it's worth being explicit as to why, because by the naked eye that code looks all too familiar.
One "spin" on this is to properly encapsulate the thread construction as well as the thread start/join behavior.
Another option is to use ThreadPool.QueueUserWorkItem(), which isn't quite the same and can result in poor ThreadPool performance if over-used.
Another option is to create a thread that is blocked on a signal, e.g. ManualResetEvent, which is set when a data member has been initialized. The target data member can be as simple as an object reference as shown above, or you could use an ArrayList, Queue or Stack object (with proper locking) to implement a sort of "queue processor" where work items can be enqueued and processed by a dedicated thread, and where the dedicated thread remains dormant (blocked waiting for a signal) until there is work available.

Categories

Resources