How to add Overlay Objects to display from a worker thread in C#

Hi @Greg,

we have investigated this and it turns out that this is in fact not a multithreading issue but a pointer aliasing problem. In the method AddOverlayObjectNET the last parameter (the pointer to the plugin data) has been marked as void* in the display control’s MIDL description (in the .Net wrappers generated by tlbimp and aximp this parameter is exposed as an IntPtr). We fully expected this to result in 64 bit being passed to the control via the IDispatch interface, but as it turns out, this is marshaled as a variant of type VT_HANDLE which is internally treated as an integer (long story short: you pass in a pointer which is converted to an integer by the CLR and then passed to the control which converts it back to a pointer from which the upper 32 bits are garbage).

The fact that you are now seeing this in you non-UI threads is coincidence more than anything else - it just happens that the overlay plugin data structure seems to usually end up inside the 32 bit address range in your UI thread and - maybe only slighty - above that in your non-UI threads.

Unfortunately this is impossible to fix without adding a new function (or modifying the existing one, which is something we decided against so that we don’t break existing applications - after all the issue is non-existent in a 32 bit process), which is what we did. The fixed ActiveX control will ship with the new version (13.1) of :cvb: which is due to be available soon (currently we’re on what will hopefully be the final release candidate). The new display control should also run fine on a 13.0 installation (if you need the OCX before the 13.1 release please PM me). Sorry for the inconvenience!

By the way: Any call that does not pass a plugin data structure will not suffer from the flaw in AddOverlayObjectNET, nor will for example AddLabel be affected. So one possibility would be to work around the issue with a label instead of the StaticTextout plugin until the fix is available.

On a different matter: I’d advise to rearrange your lambdas so that you don’t waste performance on superfluous thread transitions and synchronizations (you can do all three operations in one go):

if (cvDisp1.InvokeRequired)
{
  cvDisp1.BeginInvoke((MethodInvoker)delegate () 
  {
    cvDisp1.RemoveAllOverlayObjects(); 
    cvDisp1.AddOverlayObjectNET("StaticTextOut", "bla", false, false, 0xFF, 0xFF00, true, 1, pixelList, textData.ToIntPtr());
    cvDisp1.Refresh();
  });
}