Common Vision Blox 14.0
Common Vision Blox

THE Machine Vision Operation System

The perfect platform for vision application development.

About this Documentation

At the top level of this documentation a general introduction gives an overview of Common Vision Blox, covering the topics

Following that are sections documenting1 the Common Vision Blox

  • Image Manager and the
  • Foundation Package (the two basic modules of Common Vision Blox). Image Processing
  • Image Processing Tools and Foundation Tools are also available as single manuals here.
    Please refer CVB Release Notes for tool availability in your setup (win32, Win64,Linux).

For users unfamiliar with Common Vision Blox, it is recommended to go through the Introduction and the Image Manager chapters first to learn the basic concepts that are valid throughout all the other modules of Common Vision Blox.

Additional Online Documentation for CVB is available as:

Hints for Programming with Common Vision Blox as well as Example Applications (Tutorials) for Image Manager and Foundation Package information for Common Vision Blox may also be found in this manual and under

1Inside either of these groups, the documentation of each module always consists of the following sections:

  • An Introduction and Overview part that explains the background of the module and the implemented algorithms in enough detail to use them successfully in an application.
  • A Reference part for the DLLs and/or Active X Controls that come with the module.
    This reference part is auto-generated using the utility Doxygen.
    It lists and cross-references the available functions and definitions with their signatures.
    To map these to another language, please also have a look at the definitions in the header/wrapper file for the programming language you've chosen (usually IntelliSense or a similar mechanism will display the exact function signature in your language as soon as you type the function/type name in you development environment...).
  • Optionally a Documentation of the .Net wrapper for the module.
    This section is only present where the .Net wrapper's API differs significantly from the C/C++ API.
    This is the case where an effort has been made to create an object oriented wrapper around the plain C exports that usually dominate the Common Vision Blox API.
    Object oriented APIs significantly increase the ease of use, however it is not always easy to map methods and properties of objects to their underlying C function calls, which is why we used the tool NDoc2 to generate an MSDN-style documentation for our object oriented wrappers where applicable.

Introduction

Thank you very much for choosing Common Vision Blox!

Common Vision Blox (CVB) is a powerful, modular, flexible and innovative vision software library designed for implementing demanding image processing applications quickly and reliably.

Developed by STEMMER IMAGING, Europe's largest independent machine vision technology supplier, Common Vision Blox offers quick access to everything you need for your image processing solutions. From the very first version developed in 1997, Common Vision Blox has been continuously improved and updated to live up to the changing vision market. Common Vision Blox has traditionally been among the first software packages to support and embrace new image acquisition technologies as well as new approaches and algorithms for image analysis.

Common Vision Blox has proven itself in thousands of applications worldwide and is the preferred software choice for OEMs and system integrators alike for time critical and demanding applications. It comes with a broad selection of versatile algorithms for object recognition and classification that offer faster, more elegant and more reliable approaches than classic measurement tools.|

The Structure of Common Vision Blox


At the heart of Common Vision Blox is the Image Manager. Probably the most essential feature of the Image Manager is the implementation of a hardware abstraction layer that allows programmers to access a variety of entirely different image sources (ranging from simple file-based image sources to high performance frame grabbers and covering all relevant interface and acquisition technologies available for machine vision) through the same simple API while still enabling access to a fair amount of hardware specific functionality. That way, with Common Vision Blox a programmer does have the choice to either write completely hardware independent machine vision applications (that allow for simple drop-in replacement of the acquisition hardware) or take best advantage of the details and features his hardware offers. For a list of supported acquisition devices you can either have a look at the Drivers folder of your Common Vision Blox DVD, or visit www.commonvisionblox.com. In addition to the hardware abstraction layer, the Image Manager provides functionality for handling image data like

  • access to image data and properties
  • display images in a fast and interactive display with non-destructive overlay capabilities
  • modify image data by copying them, creating new views on them or using basic transformation functions
  • read and replay AVI, MPG or MP4 streams from disk
  • 3D data manipulation
  • demanding realtime 3D surface inspection
  • read/write image files from/to disk in various formats

The Image Manager is the most basic module of Common Vision Blox that may be purchased separately.

The Common Vision Blox CameraSuite in terms of functionality is almost identical to the Common Vision Blox Image Manager, however it is limited to those cameras that are compatible with it and does not come with a dongle to which Common Vision Blox tools may be license (see Licensing Concept). The CameraSuite can not be purchased individually - it comes for free bundled with those cameras that are supported by the Camera Suite like e.g. the the CVC camera series from STEMMER IMAGING or the AreaScan 3D cameras from VRmagic, as well as all GigE Vision and USB3 Vision cameras sold by STEMMER IMAGING.

If more functionality than what the Image Manager and the CameraSuite offer is required, then we recommended looking at the Common Vision Blox Foundation Package. This package includes the Image Manager and extends it by adding state-of-the-art image processing functionality which many machine vision applications will need, like

  • arithmetic and logic operations on image data
  • blob analysis
  • color space conversions
  • correlation
  • Fourier transform
  • various filter functions for de-noising, edge detection and morphology operations
  • statistical evaluation of image data
  • metric conversion
  • advanced transformation functions for image data
  • barcode and matrix code reading

Both basic packages, the Image Manger or the Foundation Package, may be combined with a number of more sophisticated Tools for specialized tasks like bar code reading, OCR or print inspection. These tools are sold independently, offering customers a flexible and cost-effective choice of modules to build their machine vision systems from.

On the Windows™ platform, Common Vision Blox may be used with C/C++, the .Net programming languages, or Python. On the Linux platform it may be used with the C/C++ compilers of the GNU Compiler Collection or Python.

For an explicit list of supported programming environments and versions please refer to the Common Vision Blox Release Notes (also located in your start menu and in the doc sub-directory of your Common Vision Blox installation, but also available on www.commonvisionblox.com).

Where to buy?

In the distribution area of the STEMMER IMAGING Group, Common Vision Blox may be purchased from STEMMER IMAGING directly. Outside that territory, the software is available through our growing network of distributors and partners around the world.

See https://www.stemmer-imaging.com/en-de/company/locations/ for a list of our international sites to find the one located closest to you. Refer also www.stemmer-imaging.com for getting in contact.

Download and Installation

The most up-to-date download version of Common Vision Blox and the Common Vision Blox CameraSuite can always be found on the CVB Homepage. All other CVB versions can be downloaded in CVB user forum download area.

When you downloaded the CVB installer, simply start it and go through the installation interview and let the installer work its magic...


After the Common Vision Blox installer has finished, you can download and install any additional acquisition device drivers that you might need (also available from CVB Homepage).

API Guide

Introduction

Over the past 20+ years the functionality of Common Vision Blox has been accessible through several hundred functions exported by a few dozen DLLs. These functions were exported in a way that was compatible with Visual C++, Delphi and Visual Basic - arguably three of the major programming languages for Windows applications when Common Vision Blox was first published. Starting with Common Vision Blox 13.2, this application programming interface (API) - henceforth called the C-style API (of Common Vision Blox) - has been supplemented with three newly developed APIs targeted at specific programming environments: CVB.Net, CVB++ and CVBpy. This page is intended to give a brief introduction into these three APIs, highlight the design ideas behind them and give an overview over which tools are accessible in each API.

Why new APIs?

When the C-style API of Common Vision Blox was designed, one of the aims was to support C (and the nascent C++), Delphi and Visual Basic with a reasonable maintenance effort. To that end, the API had to be more or less restricted to types and other syntactical constructs that were mappable to all target languages. A procedural API consisting of - in C terminology - extern "C" __stdcall functions and using only the most elementary data types was the logical result. A welcome side-effect of this simplicity was that the C-style API was immediately usable not only in the .Net languages when they arrived on the market in 2002 but also (though unsupported) in a number of other environments like LabView or Matlab for those users willing to put in the effort.

Today, object oriented programming and object oriented techniques and patterns are considered state-of-the-art and it has been generally accepted that these provide an ease-of-use and a degree of flexibility that is superior to procedural programming (ideally resulting in a reduced time to market for software that can build on these advantages). This already starts with the built-in features of today's development environments: If one has e.g. an image object, the development environment can easily show all the methods and properties available on that object; the same is not true if one just has a bland image handle and a number of functions that accept one of those handles. And it doesn't stop just there: Objects with a defined and automatic lifetime management are much more easily integrated into OOP-patterns than a collection of pointers and functions. And the bare minimum approach that the C-style API of Common Vision Blox had to take by necessity precludes the use of complex data types (objects) which would have been necessary to provide a consistently object-oriented approach.

Therefore the decision was made to add a consistently object-oriented API layer for Common Vision Blox. With the exception of the .Net language family such an API layer is by definition language and/or runtime dependent. Also, the implementation and maintenance effort is significant, so the number of languages/environments that can actually be supported is limited. Based on the selection criteria "platform independence", "popularity" and "flexibility" the languages/environments ultimately selected were .Net, C++ and Python, making the naming obvious: CVB.Net, CVB++ and CVBpy.


Specifications

Layers

The new APIs - CVB.Net, CVB++ and CVBpy - are all built on the C-style API (with CVBpy in turn also relying on CVB++ as its basis - simply because the implementation of the Python wrappers became much easier with the CVB++ classes than it would have been with the C-style API):


Of course this implicitly also means that the three new APIs will not make the C-style API obsolete in any way. To the contrary: It will continue to be the basis for all the other APIs and will be fully maintained in the future and will continue to be available for those who either do not want or cannot move to one of the new APIs.

Design Rationale

When designing the CVB.Net, CVB++ and CVBpy APIs, the following considerations were the cornerstones for the design decisions:

  • build lean and efficient wrappers on top of the C-style API that do not introduce a noticeable performance penalty at runtime
  • consistently use object oriented idioms to make the new APIs easily understandable and facilitate easy integration into object oriented programming patterns
  • embed the new APIs natively into their respective programming environments by adopting naming and usage patterns generally established in the respective environments so that users will not perceive the CVB API as something alien to the rest of their tool chain
  • prioritize native embedding over congruence with the C-style API - even if this means the users familiar with the C-style API may not immediately recognize everything at first sight
  • make lifetime management of CVB object automatic by using language-specific constructs like smart pointers or reference types, thus eliminating the need for "manual" reference counting which is one of the most common sources of usage errors in the C-style API.
  • use native container objects where it makes sense rather than relying on CVB-specific containers like e.g. PIXELLIST
  • raise exceptions for errors rather than just returning a simple value that may (too) easily be ignored by the caller

Stability Commitment

Although it was not put down in writing anywhere, the original C-style API of Common Vision Blox did apply a fairly strict stability commitment: The API did (more or less...) not change in the sense that function signatures were altered or functions removed entirely. Admittedly there were occasions where function behavior needed to change between versions and over the years there was the odd case where it was not possible to circumvent some of the aforementioned changes. But in general, the developers behind Common Vision Blox were working under the assumption that what has been released to the public did by default have to remain unchanged. For the C-style API this will continue to be the case.

Of course, restricting changes to the API to only the absolutely necessary ones does have its drawbacks. The entire API effectively becomes static and inconsistent naming of code items or inconsistent (or improveworthy) signature choices cannot simply be corrected as they would break compatibility on the binary level as well as on the source code level. The go-to solution in those cases is to gradually introduce new functions like e.g. ListPixelEx (which does the same job as ListPixel, only with doubles rather than ints). While fixing the problem at hand, these constructs arguably won't improve the overall appeal and quality of the API, and it was therefore decided that the CVB.Net, CVB++ and CVBpy API will be allowed to be more dynamic insofar as they may actually change between different releases!

What may - at least to some and at first - sound like a developer's nightmare is actually not so bad when looked at more closely. First of all this will allow the APIs themselves to become better over time and be easier to use and understand as they evolve. But - even more importantly - the three different APIs have different ways to deal in user-friendly ways with these changes that were not available to the original C-style API:

  • CVB.Net consists of a set of regular .net assemblies that can make use of the entire feature set of the Common Language Runtime. In particular they have been given an AssemblyVersion attribute which will allow an application built versus CVB.Net to correctly identify and load the precise version(s) of the DLL(s) against which it has been built. Furthermore, they are installed into the Global Assembly Cache (GAC) incrementally (i. e. every new version of Common Vision Blox will not only install the current build of the CVB.Net DLLs in the GAC, but also all the older released versions). Thanks to that, changes to the CVB.Net API in a later release of Common Vision Blox will not break binary compatibility with an executable that has been built versus an older version of CVB.Net!
  • CVB++ comes as a collection of header files that contain references to the C-style API functions - which will continue to be static. The actual C++ API will be compiled directly into the binaries generated with it and is not part of the DLLs in Commons Vision Blox. This is why future changes to the CVB++ API will not break binary compatibility.
  • The situation with CVBpy is somewhat different in that there is no binary compatibility to be broken as Python is usually not compiled into a stand-alone binary.

To summarize: Even with the deliberately more dynamic new APIs binary compatibility will not be broken by future changes.

Of course, changes to the existing APIs will - in all three cases - potentially break backward compatibility on the source code level. However, even these breaks can be circumvented:

  • CVB.Net applications can refer to the correct GAC-installed CVB.Net DLLs rather than the most recent ones found in %CVB%\Lib\Net and continue to compile versus older builds of the CVB.Net API.
  • Applications built versus CVB++ can continue using older versions of the API by simply copying the contents of the %CVB%\Lib\C\cvb folder into the project and using the older fileset from there.
  • Similarly, CVBpy applications can be made working again after API changes by reverting to older versions of the CVBpy wheel.

To summarize: Future API changes do not necessarily require that existing application will need to be migrated.

Any of these three cases, is not a generally recommended approach, but a quick fix for those situations where one doesn't have the time to properly migrate the source code. Keeping up with the API is generally recommended and should not actually prove too difficult - STEMMER IMAGING is committed to providing all the required information up front plus the compiler will do a good job of pointing out the code locations that need to be changed. With binary backward compatibility not actually being much of an issue and source code compatibility being at least one that can be dealt with easily, the principle "stable API at all costs" will NOT apply for CVB.Net, CVB++ and CVBpy, so signatures, names etc. may change as needed in future releases if the need arises.

Overview

The following table gives an overview of which Common Vision Blox module is supported in which API context. More detailed and API-specific usage hints and introductions are located in the "Programming with Common Vision Blox" section of the online help.

  • The first column gives the name of the DLL. Users already familiar with Common Vision Blox will likely recognize these, which makes them a good entry point. Note that not all DLLs are available for all platforms (see the different markings at the bottom of the table).
  • The three columns under the heading C-style give an overview over what tools/DLLs are accessible from which languages through the C-style API of Common Vision Blox.
  • The column CVB.Net obviously lists the modules that are accessible through the CVB.Net API. The mapping rules are fairly straightforward:
    • Everything from the Image Manager block (red background) can be found in the assembly Stemmer.Cvb.dll
    • Everything from the Foundation Package block (mint-colored background) can be found in the assembly Stemmer.Cvb.Foundation.dll
    • Everything from the tools block (gray background) has - if implemented - been put into a DLL that bears the tool name (e.g. Stemmer.Cvb.Minos.dll, Stemmer.Cvb.Polimago.dll etc.)
  • The column CVB++ lists the modules that are accessible through the CVB++ API. The mapping rules are:
    • Everything from the Image Manager block (red background) can be found in the Cvb namespace.
    • Everything from the Foundation Package block (mint-colored background) can be found in Cvb::Foundation namespace (with the sole exception of the OPC UA tool which is located in the Cvb::OpcUA namespace).
    • Everything from the tools block (gray background) has - if implemented - been put into a namespace that bears the tool name (e.g. Cvb::Minos, Cvb::Polimago etc.)
  • The column CVBpy obviously lists the modules that are accessible through the CVBpy API. The mapping rules are again fairly straightforward:
    • Everything from the Image Manager block (red background) can be found in module cvb
    • Everything from the Foundation Package block (mint-colored background) can be found in cvb.foundation module (or cvb.opcua module).
    • Everything from the tools block (gray background) has - if implemented - been put into a namespace that bears the tool name (e.g. cvb.minos, cvb.polimago etc.)
C-styleCVB.NetCVB++CVBpy
C/C++.Net
CVCore.dll
CVCore3D.dll
CVCImg.dll ocx
CVCDisp.dll ocx † 5 5
CVCDriver.dll ocx
CVCUtilities.dll
CVGenApi.dll ocx
Arithmetic.dll 3 3 3
CVCEdge.dll ocx
CVFoundation.dll ocx †
CVMetric.dll
CVOpcUa.dll 2
CVPolarization.dll 4
etBayerToRGB.dll
LightMeter.dll ocx
OpticalFlow.dll 4 4 4
TextOut.dll 4 4 4
ZXBarcode.dll 4 4
CVCBarcode.dll ocx † 4
CVCBlob.dll ocx
CVCColor.dll ocx ‡ 4 4 4
CVDirect3D.dll
CVGevServer.dll *
CVMatch3D.dll
CVSpectral.dll
Manto.dll ocx‡
MinosCVC.dll
Movie2.dll ocx † *
Polimago.dll * 6
Sil.dll 4
SF.dll ocx

Legend:

Image Manager Components
Foundation Package Components
Tools

ocx = ActiveX Control(s) available
† = No/limited availability on Linux
‡ = Win32 only
'*' = Semi-OOP wrapper (object-oriented but interfaces to iCVCImg.dll)
1 = Not available at the moment; will be made available on request
2 = Will not be available - use the CVB.Net API instead
3 = Equivalent Functionality is available through CVFoundation.dll
4 = Will be release in a future version of Common Vision Blox
5 = Default Display for CVB++ and CVBpy is Qt based component
6 = Training currently not supported - to be implemented in a future version of Common Vision Blox

Support

There are several sources for answers to your questions regarding Common Vision Blox:

  • Our frequently updated FAQ pages can be found at www.commonvisionblox.com and forum.commonvisionblox.com.
  • Online Help with documents and Application Notes can be found at here.
  • If you do not find your answers there, please contact your local sales and support representative.
  • If you acquired your copy of Common Vision Blox directly from STEMMER IMAGING, please contact:
Germany de.support@stemmer-imaging.com
Austria at.support@stemmer-imaging.com
United Kingdom uk.support@stemmer-imaging.com
France fr.support@stemmer-imaging.com
Switzerland ch.support@stemmer-imaging.com
Benelux countries nl.support@stemmer-imaging.com
Sweden se.su.nosp@m.ppor.nosp@m.t@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com
Denmark dk.su.nosp@m.ppor.nosp@m.t@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com
Finland fi.su.nosp@m.ppor.nosp@m.t@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com
Poland pl.su.nosp@m.ppor.nosp@m.t@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com

New versions of Common Vision Blox as well as Service Packs and the latest acquisition driver updates can always be found on the download page on www.commonvisionblox.com and forum.commonvisionblox.com. Common Vision Blox is a development from STEMMER IMAGING AG. For questions and suggestions feel free to contact us directly under

STEMMER IMAGING AG
Gutenbergstraße 9-13
D-82178 Puchheim
Germany

Sales: +49 (0) 89 80902-299
Support: +49 (0) 89 80902-200
E-mail: de.sa.nosp@m.les@.nosp@m.stemm.nosp@m.er-i.nosp@m.magin.nosp@m.g.co.nosp@m.m
de.support@stemmer-imaging.com
Internet: www.commonvisionblox.com
forum.commonvisionblox.com

Copyright and Acknowledgements

The software described in this document is furnished under a license agreement. The software may be used or copied only in accordance with the terms of the agreement. It is against the law to copy the software except as specifically allowed in the license agreement. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or information storage and retrieval systems, for any purpose other than the purchaser's personal use, without the express written permission of STEMMER Imaging. Information in this document is subject to change without notice.

The following names are trademarks or registered trademarks:

  • Common Vision Blox™ is a trademark of Integral Vision, Inc. and STEMMER IMAGING AG
  • Microsoft®, Visual Studio®, Visual C::® , Visual C++®, and Visual Basic® are registered trademarks of Microsoft Corporation
  • Borland®, Delphi®, C++ Builder® are registered trademarks of Borland Corporation today owned by Embarcadero.
  • Codegear™ is a trademark of Borland Corporation today owned by Embarcadero
  • Win32®, Windows®, Windows XP®, Windows 7®, Windows 8®, Windows 10® and Windows VISTA® are registered trademarks of Microsoft Corporation
  • CodeMeter® is a trademark of the WIBU Systems GmbH

Refer also Open Source Licenses in Common Vision Blox (or OpenSourceLicenses.pdf in %CVB%Doc).

Throughout this document the names of several companies and products that are not trademarked by STEMMER IMAGING and not included in the above list may be mentioned. Mention of these companies or products by no means implies an endorsements of Common Vision Blox by the respective trademark owners.

Licensing

Common Vision Blox offers different licensing methods. In each case the licensing can be managed via the License Manager.

  • USB dongle: The dongle method is straightforward and is not discussed in this document.
  • CameraSuite licensing: The Camera Suite licensing model allows PCs to have an Image Manager License when a suitable GigE Vision/USB3 Vision camera is connected to the PC.
  • Node Locked licensing: Node Locked licensing involves locking the license to the target PC's hardware.
  • 30-day Trial licensing: The 30-day trial license is a special case of the Node Locked license.

The Licensing Concept allows each individual tool plus complete applications to be protected by a single system-wide protection method. The licensing methods can be selected by using the License Manager.

Most CVB features will run in Evaluation or Demo Mode, but with a restricted functionality. This means that although the functions are available, security dialog boxes or watermarks will be displayed periodically.

Protecting applications and tools

The CVB Image Library includes a function that returns the product's serial number and this is used whenever a protected CVB function is called. If the serial number is available to a CVB tool or application it can be used for security encryption. Generally, the serial number is used as a variable to calculate a so-called magic number. The formula for calculating magic numbers is known only to the developers. CVB Tools and applications can be individually protected using this unique tool or application formula.

Applications can store their magic number in the LICENSE.INI file and the magic number is read from the license file at runtime. This number is then checked against the serial number of the protection method being used.

Each CVB Tool magic number must be used in order to activate the tool. Using a single protection mode for a range of Common Vision Blox tools and applications reduces costs and increases user satisfaction.

Concept

Licensing in Common Vision Blox relies on two items:

  • the Common Vision Blox serial number and
  • the (tool-related) Magic Number.

Together, those two allow for a flexible and modular licensing concept that fits the modular nature of Common Vision Blox.

  • Starting with Common Vision Blox 11.x, Common Vision Blox licenses will by default shiped with a WIBU CodeMeter USB dongle.
    The hitherto used SafeNet Sentinel SuperPro will continue to be available upon request for duplicating existing installations based on older versions of Common Vision Blox, but will only support the Win32 version of Common Vision Blox (whereas the CodeMeter dongle will work for all supported platforms).
  • The underlying architecture for querying license information from the dongle or other license providers has been changed to use asynchronous mechanisms in order to eliminate the timing differences between the different license providers.
    In other words: the dongle licenses will not react any slower than e.g. Node Locked Licenses and an individual license query will typically take less than 1 millisecond.
  • It is possible to use several different licenses simultaneously.
    If, for example, you own a dongle for which you have the Magic Number for Minos, and another one for which you have the Magic Number for CVC Blob you may simply plug in both dongles, add both Magic Numbers to the License.ini file and use both tools in one application.
    Please note that as a consequence the functions GetSerialNumber and GetLicenseInfo are no deprecated as they cannot be adapted to this scenario.
    They have been replaced by UpdateLicenses, GetLicenseCount and GetLicenseInfoEx (see the reference documentation for the CVCImg.dll for details).
  • Customers buying one of the new WIBU CodeMeter dongles with a Common Vision Blox License and simultaneously one or more Common Vision Blox tool Magic Numbers will no longer need to enter these Magic Numbers into the License.ini file because in this scenario STEMMER IMAGING will write them directly into the dongle.
    This makes porting all the licenses from one PC to another significantly easier.
  • In addition to the Common Vision Blox Serial Number and the Foundation Package Flag a license provider will now potentially report additional license properties:
    • Common Vision Blox Major version(s) for which the license is valid
    • Platform on which the license is valid
    • Expiration date of the license (optional)
  • The CVB License Manager can be used to display these new properties of Common Vision Blox Licenses.
  • It is no longer necessary to specify the Magic Numbers for Common Vision Blox Serial Number 999 – the system already knows them.
    Consequently, users activating a time-limited Trial License will no longer receive a *.lic file along with the activation key.

Common Vision Blox Serial Number

The Common Vision Blox Serial Number is a unique integer number that is issued whenever a customer purchases a Common Vision Blox Image Manager or Foundation Package license. By convention, some of these numbers have been reserved for specific license types (for example, serial number 0 indicates the Common Vision Blox Camera Suite – see next section for details – and serial number 999 is always being used for time-limited Trial Licenses of Common Vision Blox), but generally these numbers are just being counted and no number is ever issued more than once (with the obvious exception of 0 and 999).

The source of a Common Vision Blox Serial Number can be one of the following:

Serial Number Provider Supported Platform License Type
USB dongle (WIBU CodeMeter) Any Full
USB dongle (SafeNet Sentinel SuperPro)1 Windows (32 bit) Full
Parallel Port dongle (SafeNet Sentinel SuperPro)1 Windows (32 bit) Full
Host Hardware Characteristics (Node-Locked Licenses) Any Full/Trial
GigE Vision Cameras Any CameraSuite
USB3 Vision Cameras2 Any CameraSuite
STEMMER IMAGING CVC/FGI Cameras Any CameraSuite
VRmagic AreaScan 3D Cameras Windows (32 and 64 bit) CameraSuite

1 Legacy devices (not recommended for new applications)
2 Introduced in Common Vision Blox 2016

In Addition to the aforementioned integer number, a Common Vision Blox Serial Number has one or more of the following properties:

  • Common Vision Blox Major Version
    Starting with Common Vision Blox 2011, Common Vision Blox Serial Numbers will no longer have an unlimited version scope: A Serial Number issued once will be valid for all Common Vision Blox Releases with a matching Major Version number. For newer Major Versions a license upgrade may at some point be required.
  • Foundation Package Feature Flag
    The presence or absence of this flag decides whether or not the Common Vision Blox Foundation Package is licensed.
  • Platform
    As indicated in the list of license providers, not all license providers will be usable on all platforms.
  • Expiry Date
    Common Vision Blox Serial Numbers may be time-limited, which means they will cease to exist on a given date (currently only used for trial licenses).

The availability and the values of these flags may be verified using the CVB License Manager which will be presented in more detail further down this document.

Common Vision Blox CameraSuite

The Common Vision Blox CameraSuite is a Licensing Model designed for users who want to use Common Vision Blox as a versatile SDK for their image acquisition hardware. Technically speaking, CameraSuite Licenses present themselves as a license with the Common Vision Blox Serial Number 0 that is available as soon as the hardware to which the license refers has been plugged in (and – in some cases – an activation key has been entered).

With a Common Vision Blox CameraSuite license the whole functionality of the Common Vision Blox Image Manager may be used without any restrictions. It is, however, not possible to license the Foundation Package or any of the Common Vision Blox tools with a CameraSuite – for this, a Common Vision Blox Image Manager or Foundation Package license must be available on the system.

If you have an image acquisition device that has been supplied with a CVB CameraSuite Activation Code, it can be used to activate the Common Vision Blox CameraSuite functionality.

The activation code for activation are to be found as follows:

  • The activation code will be also retrieved automatically, if the camera is connected to the system and the system has access to the internet.
  • If the system is not connected to the internet, you can retrieve the activation code from the license sticker on the package of your GigE Vision or USB3 Vision camera from STEMMER IMAGING.
  • Or on our CVB License key request website through entering the MAC address of the GigE cameras and the serial number of USB3 cameras.

Please use the CVB License Manager to activate your license.

Tool-related Magic Numbers

"Magic Numbers" in this context are strings consisting of alphanumeric characters that are issued when a customer purchases a license for a Common Vision Blox tool. These Magic Numbers are tool-specific, and at the same time specific to the Common Vision Blox Serial Number for which they have been bought (this is the reason why a Common Vision Blox Serial Number needs to specified when purchasing a tool license).

There are two possible locations where a Tool Magic Number may be stored:

  • A WIBU CodeMeter dongle
    If you purchase a new Common Vision Blox Serial Number in a CodeMeter dongle along with one or more Tool Magic Numbers, STEMMER IMAGING will automatically write those Magic Numbers into the WIBU CodeMeter dongle.
    Once plugged in, all the required license information for Common Vision Blox as well as the tool(s) involved will automatically be available.
  • The File %CVBDATA%\License.ini
    If you purchased Tool Magic Numbers for a Node Locked Common Vision Blox Serial Number or for a USB dongle that you already possess, you will receive a text file whose contents can be imported into the License.ini file by means of the CVB License Manager.

At Runtime a tool will verify its Magic Number versus the Common Vision Blox Serial Number(s) in the system. If a match is made, the tool will run unrestricted. Otherwise tool-specific limitations (e.g. a reduction in result precision or watermarking of result images) may apply. Tools that do not rely on watermarking to disrupt unlicensed use will display a message box indicating the restriction(s).

Node-Locked Licenses

The "Node-locked" method, is a way of licensing Common Vision Blox that is not tied to a dongle but instead uses hardware specific information that is generally available on a computer; for example, the CPU, network adapter or hard drive. The "node-locked license" is requested and delivered by email.

To request a node-locked license, start the CVB License Manager, run Node Locked from the tasklist and press the Purchase Node Locked License button.

Evaluation Licenses

If you want to evaluate Common Vision Blox before purchasing a license, there are generally two options:

  1. You can start using Common Vision Blox straight away without a license and work in evaluation mode.
    Evaluation mode means that the Image Manager, Foundation Package or advanced tools will more or less behave as it would if a license were present, but apply some restrictions to make it unsuitable for productive purpose.
    Some functions will, for example, add a watermark to the images that have been processed while others will display a message box every few minutes.
  2. The more satisfying alternative is to order a trial license.
    Trial licenses are in principle node-locked licenses with a limited validity period of 30 days that cover every Common Vision Blox module.
    Trial licenses can be ordered using the CVB License Manager - simply go to the "Node Locked" section and press the "Get Free Trial License" button.
    After entering your contact details you will be prompted to send a file with your request data to cvbli.nosp@m.cens.nosp@m.e@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com and an activation code will be sent to you within one work day.
    As an in-depth evaluation might actually take longer than 30 days, trial licenses will be issued more than once if required.
    In other words: It is perfectly fine to order two or more trial licenses if your evaluation takes longer.

Using the Common Vision Blox License Manager

License entries can be managed using the Common Vision Blox License Manager:


For more details refer also the CVB online help (First steps with CVB -> How to get CVB licensing).

Getting Started

Detection, access and management of devices, getting live views and license administration can be operated by

Find the operating instructions in the following chapters and in CVB Configurator.

CVB Programmers Reference (C, C++, .Net and Python API) is the entry point for using the CVB SDK.

Details according to GenICam compliant hardware and drivers used with Common Vision Blox are described in the:

Additional Common Vision Blox Online Help can be found here :

GenICam Browser

For browsing, configuring and changing available and configured GenICam complient devices and features the CVB GenICam Browser can be used. With the GenICam Browser you can easily configure the INI file (in %CVBDATA%Drivers) in order to use your application with the GenICam.vin driver located in %CVB%Drivers folder. Refer Help file menu in GenICam Browser for detailed tool documentation and GenICam User Guide.



License Manager


Configure/Request your licenses using the Options from License Manager.

Start the LicenseManager.exe from Windows start menu or from %CVB%Applications.


Order Trial License to get full functionality of CVB Tools and SDK for 30 days:


A detailed description of the different license methods can be found in section Licensing.

Edit Bindings

Bindings are fixed connections between a GenApi xml file and a specific device, identified by its (device-specific) ID. If a binding has been defined for a device, it overrides the linked xml file; in other words: Bindings are a means of making sure that a specific device will use a specific xml file.

In order to control which xml file will be used for a given GenICam device in th CVB GenICam registry the console application EditBindings can be used. After defining bindings and links in that registry, they apply to any device that may be addressed through the GenICam.vin.

EditBindings can be found in:

  • Windows: %CVB%Hardware\StemmerImaging\Utilities
  • Linux: /opt/cvb/bin

CVB Software Development Kit (SDK)

CVB Image Manager

The CVB Image Manager is the basis for every Common Vision Blox application. The unique functionality and approach of the CVB Image Manager as an open standard provides an excellent basis for custom algorithms and applications in industrial image processing.

  • The manual of the image manager can be found here.
  • Dlls and functions are listed here.

CVB Foundation

The Common Vision Blox Foundation Package is a complete easy to use comprehensive collection of optimised image processing functions. Based on the CVB Image Manager that offers unique functionality in image acquisition, image handling and image processing, it contains an extensive set of image processing functionality allowing you to control many different types of image acquisition hardware, as well as providing an optimised image display.

  • Manuals, Dlls and functions of the foundation package and tools can be found here.

CVB Tools


Common Vision Blox not only supports you with a range of optimised tools, but also offers you the freedom to embed your own know-how and to implement innovations quickly. Combine multiple tools to create the best solution.

  • A list of the tools (Dlls and functions) and detailed manuals can be found here.

Programming with Common Vision Blox

Common Vision Blox is currently the worlds most powerful, flexible and innovative vision software for quickly and reliably implementing your image processing applications. CVB supports all common Windows™ compilers enabling you to program with the imaging libraries as easily as possible.

Refer to CVB library, download and the API.

  • Compiler specific hints
    To speed up your development and make it as easy as possible we give you here an introduction of the supported Compilers and a programming approach for every supported Compiler.
  • Multi-Platform information
    Find hints for Win32 and Win64 system usage, as well as Linux information, development from scratch, portable code and breaking changes.
  • Hello CVB
    Create a very basic application that simply acquires and displays live images.
  • Starting with the Image Manager
    Work with CVBs core machine vision technologies in image acquisition, image handling, image display and image processing.
  • Example Applications and Tutorial programs
    Get profit from already executable CVB tutorial programs for every supported programming environment and use the source code and sample images for your own development.
    Some of them are described in this manual, refer the Example Applications chapter.
    Hints for System Setup can be found in Getting Started with CVB Tutorials Guide.
    Refer also %CVB%\Tutorial directory and CVB API.
    There are some more Examples and Use Cases.
  • Foundation Package
    Based on the CVB Image Manager, the Foundation Package contains an extensive set of image processing functionality allowing you to control many different types of image acquisition hardware, as well as providing an optimised image display.
    Find functionality for edge detection, blob analysis and the segmentation of objects or functions for statistical image analysis or correlation of images, as well as functions for filtering of images or superimposing destructive text overlays.
    CVB Foundation Package also provides an extensive range of arithmetic and logical functions, it even contains functions for binarization using dynamic thresholding, different colour conversion functions, Bayer to RGB decoding and an algorithm for 2D spatial calibration of image data.

    Refer also %CVB%\Tutorial\Foundation directory.

Compiler specific hints

CVB supports all the common Windows™ compilers, enabling you to program with CVB imaging libraries and controls as easily as possible. The supported compilers list depends on the different supported operating system and the corresponding available compilers.

Please have a look at the current CVB Release Notes for details about the supported compilers, version and update infos.

For example for Windows Common Vision Blox supports the visual programming environments (compilers)

  • Microsoft Visual C++®
  • Microsoft Visual C.Net®
  • Microsoft VB.Net®
  • Microsoft Visual C#.Net®/CSharp
  • Borland C++Builder®
  • Borland Delphi®
  • Microsoft Visual Basic®

In this chapter you will find a lot of useful hints and background informations regarding the support and use of CVB with compilers.

.Net and CVB Programming Hints

This section gives practical hints for using CVB with .Net:

Additionally you should use the CVB forum tutorial Getting Started with CVB.Net.

There is also a chapter which is not necessary but very helpful to understand the issue "unmanaged code and managed .Net projects". This is for interested and experienced .Net users.

.Net Programming Hints -Using CVB libraries

In the .Net programming languages (C#, VB.Net, C++/CLI or in fact any other CLR-based language) the Common Vision Blox DLLs are included through managed wrapper DLLs that import the functions exported by the native DLLs through DLLImport attributes and expose them to managed assemblies through member functions of static classes. The Common Vision Blox installer installs at least two sets of these wrapper DLLs:

  • One in the global assembly cache (which can be browsed by opening a Windows Explorer to the folder C:\Windows\assembly) and
  • one in the folder %CVB%\Lib\Net.

The latter location always only contains the very latest version of the managed wrappers for Common Vision Blox, whereas the global assembly cache potentially holds several of them: The very latest plus all older versions back to the last major update. This makes sure that when a managed program has been compiled versus e.g. Common Vision Blox 11.0 it is still usable on an installation of the most up-to-date Common Vision Blox without recompiling it.

To use one of the managed wrappers of Common Vision Blox you will need to add it to your project's references. The precise approach to this varies between programming languages and Visual Studio version.

Unlike in unmanaged languages like C/C++ or Delphi, in .Net even static functions always have to be member functions of a class or struct, and each entity has to be part of a name space. Therefore it is in those languages not possible to simply write the function name (e.g. CreateGenericImage(...)) - instead the whole path to the function needs to be given. The mapping from the unmanaged function name to the name space and class in the managed domain is not visible from the Common Vision Blox documentation, but should be more or less apparent. If not, the Visual Studio Object Browser can help you find what you are looking for. Remember that it is possible to omit the leading name space(s) (like Cvb.) by adding a using (C#) or Imports (VB.Net) statement.

How to include libraries in your managed .Net project

Before you can do anything with CVB in .Net, you need to add the references to our Stemmer.Cvb assemblies:


In the opened dialog switch to Browse and click on the Browse… button:


Enter %CVB%Lib\Net in your address list to jump to the CVB library directory for .Net. Ignore the iXXX.dll group of DLLs (e.g. iCVCImg.dll) – these are the C-style P/Invoke assemblies. We are interested in the Stemmer.Cvb.* assemblies.

Assemblies

Image Manager (and thus CameraSuite):

  • Stemmer.Cvb.dll
    This is the core assembly containing basic Image and Device handling including acquisition via Streams and configuration (like GenICam GenApi or IDeviceControl). This combines now the functionality of CVCError.dll, iCVCImg.dll, iCVCDriver.dll, iCVCUtilities.dll, and iCVGenApi.dll.
  • Stemmer.Cvb.Forms.dll
    The CVB Display and GenApiGrid for Windows Forms apps. If you reference this one Stemmer.Cvb.Extensions.dll and Stemmer.Cvb.Aux.dll are needed. This combines the functionality of the CVDisplay ActiveX and CVGenApi ActiveX controls.
  • Stemmer.Cvb.Wpf.dll
    The CVB Display and GenApiGrid for WPF apps. You also need Stemmer.Cvb.Extensions.dll if you reference this assembly. In principle this also combines the functionality of the CVDisplay ActiveX and CVGenApi ActiveX controls. The display is a pure WPF implementation, though.
  • Stemmer.Cvb.Aux.dll
    This is needed by the Stemmer.Cvb.Forms.Controls.Display for native interop handling (mostly overlay related).
  • Stemmer.Cvb.Extensions.dll
    In here we put extension methods especially for the System. Drawing namespace to be able to support .Net Core.

Foundation Package:

  • Stemmer.Cvb.Foundation.dll
    All Foundation functions and Foundation tools are bundled in here covering for example correlation, filtering, non-linear calibration, blob, optical flow and more. Combined in here is the functionality of the iCVCFoundation.dll, iBayerToRGB.dll, iCVCEdge.dll, and iLightMeter.dll.

Tools:

  • Stemmer.Cvb.Manto.dll
  • Stemmer.Cvb.Minos.dll
  • Stemmer.Cvb.Movie2.dll
  • Stemmer.Cvb.Polimago.dll
  • Stemmer.Cvb.SampleDatabase.dll
    (Sample Image List (SIL) handling)
  • Stemmer.Cvb.ShapeFinder.dll

Using the library functions

We support the standard for documentation of .Net. Therefore we provide the so called IntelliSense, means the documention of functions available in the source code to make programing easier.

The namespace for our CVB libraries is Stemmer.Cvb. The classes are the names of the libraries, e.g. Image, Driver ...

Means to use the Image Dll function IsGrabber looks like this:

  • CVB.Net:
    CheckBoxGrab.Enabled=Cvb.Image.IsGrabber(Cvb.Image.ToCvbOBJ(AxCVimage1.Image))
  • CSharp:
    CheckBoxGrab.Enabled=Cvb.Image.IsGrabber(axCVimge1.Image);

Hints: It is possible to make the job easier and to use only the real function name instead of the whole notation with <namespace.class.function>.

Related Topics: Importing Native Dynamic Link Libraries

.NET Programming Hints - Importing ActiveX Controls

The easiest way to use one of the Common Vision Blox ActiveX controls in any of the Visual Studio languages (managed as well as unmanaged) is to import the ActiveX control into the GUI Toolbox of Visual Studio. This needs to be done only once per environment - the Toolbox items will be stored persistently by Visual Studio.

To add an ActiveX control to the Visual Studio Toolbox, go to the Tools menu choose Choose Toolbox Items or right click on the Toolbox and select Choose Toolbox Items from the context menu (in the context menu it is also possible to remove items or create groups for them). Doing so will open the Customize Toolbox dialog box with a list of all registered ActiveX Components:


Check all the components you want to add to the Toolbox (the Common Vision Blox components' naming pattern is Common Vision ... Control) and press OK. This will add the selected components to the Toolbox - next time you create a new project with Visual Studio the selected Common Vision Blox controls will already be available in Visual Studio's Toolbox.

From here on, the imported ActiveX controls may be simply be used by dropping them into the GUI designer. If the designer is the Windows Forms designer, dropping the ActiveX control onto the form will automatically create and reference appropriate wrapper DLLs for managed languages (in C++/MFC applications an additional step is required to prompt the generation of the wrappers). If you are planning to target the x64 platform as well (either explicitly or implicitly through an AnyCPU build) you might want to have a look at the section about using ActiveX controls in a .Net application for 64 bit.

Common Vision Blox Display Control

The Common Vision Blox Display Control does have two methods that are inherently incompatible with .Net languages: AddOverlayObject and AddUserObject. Both expect the caller to pass the address of the first element of an array as an integer variable, but the Common Language Runtime has no means of determining the actual length of the array for the purpose of marshaling and will only pass one integer value across the managed/unmanaged boundary. To work around this issue, the methods AddOverlayObjectNet and AddUserObjectNet have been added to the Common Vision Blox Display Control. Those methods should be used whenever trying to add a user or overlay object to the display control.

Please also note that using user objects in managed code has limitations. When user objects are being used, the Display control will raise the UserPaint event in which the (unmanaged) handle to the display's Device Context is being passed. To use the drawing functions in System.Drawing this handle can (and needs to) be wrapped in a System.Drawing.Graphics object, but doing so will slightly change the settings of the device context and make e.g. XOR painting (which is potentially used by the Common Vision Blox display) impossible. Therefore user object painting cannot be expected to behave the same way in managed code as it does in unmanaged applications.

.Net Programming Hints - Performance Improvement

When using unmanaged binaries like the Common Vision Blox DLL or ActiveX controls in a managed application, the data for function calls need to be passed back and forth ("marshaled") between the managed and the unmanaged domain. The Common Language Runtime (CLR) performs fairly strict and potentially time consuming tests in an effort to ensure the managed application's stability. Therefore it is generally desirable to keep the managed-unmanaged transitions to a minimum.

Marshaling comes in two flavors named COM-Interop and P/Invoke. The latter is applied to regular DLL function calls, while the first is reserved for COM objects (and therefore also applies to ActiveX controls). As COM-Interop calls are significantly slower, the general rule to keep the managed-unmanaged transitions to a minimum becomes a lot more urgent when dealing with ActiveX controls. A poorly shaped loop over an Image control's ImageWidth and ImageHeight properties can easily slow a loop that could otherwise be processed in a few milliseconds down to seconds!

Consider for example the following sample code (to be compiled with the /unsafe flag) that inverts plane 0 of an image:

[...]
for (int y=0;y<axCVimage.ImageHeight;y++)
{
IntPtrimageBaseAddress;
IntPtraddrVPAT;
Cvb.Image.GetImageVPA(AxCVimage.Image,0, out imageBaseAddress, out addrVPAT);
Cvb.Image.tagVPAEntry* pVPAT=(Image.tagVPAEntry *)addrVPAT.ToPointer();
byte *pImageLine=(byte*)imageBaseAddress+pVPAT[y].YEntry;
for(int x=0;x<axCVimage.ImageWidth;x++)
{
*(pImageLine+pVPAT[x].XEntry)=(byte)(255-*(pImageLine+pVPAT[x].XEntry));
}
}
__int3264 Image

Simply by caching a few values and taking them outside the loop the function executes about 1 to 2 orders faster:

[...]
int imgHeight=axCVimage.ImageHeight;
int imgWidth=axCVimage.ImageWidth;
IntPtrimageBaseAddress;
IntPtraddrVPAT;
Cvb.Image.tagVPAEntry* pVPAT;
Cvb.Image.GetImageVPA(axCVimage.Image,0, out imageBaseAddress, out addrVPAT);
pVPAT=(Image.tagVPAEntry*)addrVPAT.ToPointer();
for(int y=0;y<imgHeight;y++)
{
byte *pImageLine=(byte*)imageBaseAddress+pVPAT[y].YEntry;
for(int x=0;x<imgWidth;x++)
{
*(pImageLine+pVPAT[x].XEntry)=(byte)(255-*(pImageLine+pVPAT[x].XEntry));
}
}

Display Control with .Net

The Common Vision Blox Display Control does have two methods that are inherently incompatible with .Net languages:

  • AddOverlayObject and
  • AddUserObject. Both expect the caller to pass the address of the first element of an array as an integer variable, but the Common Language Runtime has no means of determining the actual length of the array for the purpose of marshaling and will only pass one integer value across the managed/unmanaged boundary.

To work around this issue, the methods

  • AddOverlayObjectNet and
  • AddUserObjectNet have been added to the Common Vision Blox Display Control that should be used whenever trying to add a user or overlay object to the CV Display Control.

Please also note that using user objects in managed code has limitations. When user objects are being used, the Display control will raise the UserPaint in which the (unmanaged) handle to the display's Device Context is being passed. To use the drawing functions in System.Drawing this handle can (and needs to) be wrapped in a System.Drawing.Graphics object, but doing so will slightly change the settings of the device context and make e.g. XOR painting impossible. Therefore user object painting cannot be expected to behave the same way in managed code as it does in unmanaged applications.|

Further .Net Programming Hints

This section gives a short introduction on how non-managed resources can be imported to managed .NET projects:

A more detailed description on inter-process communication between managed and unmanaged code can be found in the .NET Framework help under Programming with the .NET Framework and Interoperating with Unmanaged Code.

.NET Programming Hints - Importing Native Dynamic Link Libraries

Importing Native Dynamic Link Libraries

If a native DLL of a CVB Tool has NO .NET wrapper you can write your own to access the functions in it. For all the Image Manager DLLs and some CVB tool DLLs we already provide wrapper DLLs and the Code Documentation *.xml for the Intelli Sense. A reference how to include the wrapper DLLs in your projects please could be found here.

To write your own .NET wrapper requires more work than importing an ActiveX Control. You can create a wrapper class which grants access to the needed DLL. To write a C# wrapper you need the header file of the DLL to import. According to the given declarations the functions can be imported and types can be created. The C# wrapper class can be compiled as a DLL and added to a project as described in Importing ActiveX Controls or simply added uncompiled (Add Existing Item in the Solution Explorer).

Functions

Generally all imported functions are defined as follows:

public static extern<Return-Type><Function-Name>(<Parameters>)

so that the compiler knows that the functions can be accessed freely and that they are defined externally.

To show the compiler where to find the function and how to interprete the DLL an attribute has to be used:

[DllImport("<DLL-Name>",CharSet=System.Runtime.InteropServices.CharSet.Ansi)];

That is all the .NET environment needs to invoke and handle the function.

Example:

Here the GetGlobalDirectDrawEnabled function from the CVutilities.dll will be imported. At first have a look at the function in the header file:

IMPORT(BOOL)GetGlobalDirectDrawEnabled(BOOL&value);
cvbbool_t GetGlobalDirectDrawEnabled(cvbbool_t &value)

This function returns a BOOL (not a bool, see Data Types and Marshalling) and expects to get a BOOL as reference. In C# two options for parameters as references are available: ref and out.

We can use out here because the function simply returns the value and does not process the given BOOL. Thus according to the description above the code should look like this:

[DllImport("cvcutilities",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static externboolGetGlobalDirectDrawEnabled(outboolval);

In most cases the importing will be as simple as described here. Many functions also use custom structs and enums. Some exceptions from the simple importing process shown here are described in Data Types and Marshalling.

Constants, Structs, and Enums

Some functions with more complicated interfaces expect and/or return custom structs. When creating these structs make sure that their contents have the same order as they have in the header file. Also the following attribute should be inserted before the structure definition if it contains more than one data type to ensure the data is laid out in memory correctly:

[StructLayout(LayoutKind.Sequential)]

As a rule of thumb return types or parameters which have a range of numbers should be encapsulated in an enum - even if they are defined as constants in the header file. This guarantees type safety and eases program verification, readability and debugging.

.NET Programming Hints - Data Types and Marshalling

Data Types and Marshalling

In most cases the simple scheme of importing functions as described can be used. But there are also cases where the default marshalling doesn't succeed and the compiler has to be informed how to transform managed .NET code to unmanaged and vice versa. The way to do is the same as before: Using an attribute:

[MarshalAs(<UnmanagedType>)]

for parameters or

[return:MarshalAs(<UnmanagedType>)]

for return values. The <Unmanaged Type> is an enumeration (UnmanagedType) which defines how to handle the data type following the attribute. Now a few points are introduced where problems result. The correct marshalling of structs which contain nonprimitive data types goes beyond the scope of this introduction. Please refer to the .Net Framework help.

Arrays

C-Style arrays are defined as pointers of a certain type. Thus the compiler has to be told that this pointer should be handled as an array. This is done by marshalling an array as UnmanagedType.LPArray.

Example:

As an example the ImageHistogram function is used. The function is defined as follows:

IMPORT(bool)ImageHistogram(IMGI, longIndex, longDensity, TAreaArea, THistogram& HGram);
cvbval_t THistogram[256]
cvbbool_t ImageHistogram(IMG Image, cvbval_t PlaneIndex, cvbdensity_t Density, TArea Area, THistogram &Histogram)

We assume that the IMG definition was already made. The IMG type is a struct which contains the handle to an image. On a 32 bit system long is 32 bit value and thus an System.Int32 (or int for short). TArea also is assumed to be defined earlier and contains all coordinates of an area. In .NET we don't need the THistogram type-definition; it is a simple int-array with 256 entries (8 bit images).

The simple conversion described above would be:

[DllImport("cvcimg",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static extern boolImageHistogram(IMG img, inti ndex, int density, TArea area, int[] histogram);
void * IMG

Two MarshalAs attributes are needed for this function: First we need the marshalling for the array and second the marshalling for the return type (see bool):

``[DllImport("cvcimg",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
``[return:MarshalAs(UnmanagedType.U1)]
``public static extern bool ImageHistogram(IMG img, int index, int density, TArea area,[MarshalAs(UnmanagedType.LPArray)]int[] histogram);

bool

If a bool, not a BOOL, data type is used (C/C++ data types), it can happen that the value is always true. The reason is that the default marshalling expects a BOOL value which is stored in a 32 bit variable. bool on the other hand is stored in a 8 bit variable. Thus, especially when a bool is returned, random numbers can be found in the preceding 24 bits. That very often leads to a number unequal zero and therefore results in a true-value even when the last 8 bits only contain zeros. The solution of this problem is to tell the compiler that it should marshal this value not as a 32 bit variable but as an 8 bit variable: This is done by marshalling the value as UnmanagedType.U1.

Example:

As an example the IsImage function is used. The header file of the CVimg.dll contains this entry:

IMPORT(bool)IsImage(OBJP);
cvbbool_t IsImage(IMG Image)

We assume that the OBJ definition was already made. The OBJ type is defined as a struct which manages the handle to the object to be checked. The simple conversion would lead to:

[DllImport("cvcimg",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static extern bool IsImage(OBJ obj);
void * OBJ

But exactly this implementation would lead to the problem described above. Thus the MarshalAs-attribut for the return value is added:

[DllImport("cvcimg", CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
[return:MarshalAs(UnmanagedType.U1)]
public static extern bool IsImage(OBJ hnd);

string as output parameter

In most cases the default marshalling for strings will work fine because of the CharSet definition in the DllImport attribute. When a string is an expected output parameter the importing is more complicated: A string can not be marshalled as every unmanaged string type and no maximum size can be set. To bypass this problem the StringBuilder is used instead and marshalled accordingly (e.g. as UnmanagedType.LPStr).

Example:

In this example the GetCVBDirectory function will be imported. The definition in the header file is:

IMPORT(BOOL) GetCVBDirectory(LPSTR Directory, long lMaxLen);
cvbbool_t GetCVBDirectory(char *Directory, size_t Length)

An LPSTR is a char-array (thus a pointer to a char) and a long a 32 bit value (on a 32 bit system). The char array can be marshalled to a managed string and the long can be interpreted as a System.Int32 (or int for short). The simple conversion would lead to the following:

[DllImport("cvcutilities",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static extern bool GetCVBDirectory(out string directory, int maxLen);

But this won't wor even when the string is marshalled as UnmanagedType.LPStr, because the string can not be marshalled as this type. Instead we use the StringBuilder found in System.Text:

[DllImport("cvcutilities",CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static extern bool GetCVBDirectory([MarshalAs(UnmanagedType.LPStr)]System.Text.StringBuilderdirectory, int maxLen);

The StringBuilder given as the parameter has to have a length of at least maxLen. Otherwise the .NET framework will throw an exception. For easier handling and for ensuring the minimum length of the StringBuilder a wrapper method that returns strings can be used:

public static bool GetCVBDirectory(outstringdirectory,intmaxLen)
{
System.Text.StringBuilderbuffer=newSystem.Text.StringBuilder(maxLen);
bool result=GetCVBDirectory(buffer, maxLen);
directory=buffer.ToString();
return result;
}

This wrapper matches the method definition of the first try to import the dll function. When this wrapper is used the method to import the function should be private.

Multi-Platform

Throughout this chapter, the abbreviations Win32, Win64 and Linux refer to the supported Windows and Linux operating systems for 32 and 64 bits. For a detailed list of supported operating systems please always refer to the Common Vision Blox Release Notes. Currently the only programming environments officially supported by CVB on the Win64 platform are Visual Studio (2008, 2010, 2015). Consequently this chapter concerns itself exclusively with C++ and C# (C# having been selected as a typical representative of the .Net programming languages). Of course the concepts relevant for .Net are easily transferable from C# to any other CLR language.

Common Vision Blox on Windows x64

One of the goals when designing Common Vision Blox for Win64 was to make it as similar to the Win32 version as reasonably possible. Therefore, the %CVB% folder generated by the Win64 setup looks very similar to that on an x86 machine, and you will recognize many items you might know from the 32bit version of Common Vision Blox in their familiar locations. However, there are a few differences:

  • Of course the binaries installed on the Win64 machine have either been compiled for the AMD64/EMT64 architecture or (in case of .Net assemblies) for the “Any CPU” platform that adapts to the CPU architecture during runtime.
    To make identification of the platform for which our native binaries have been compiled easier, we did add this piece of information to the binary's version resource:


  • Several Tool DLLs and ActiveX controls are missing on the Win64 platform.
  • A new folder, Wow6432, has been added under %CVB%, containing several ActiveX controls and DLLs and source code files. The contents of this folder help us bridge the gap between the 64bit world and Visual Studio (which - like Delphi XE2 - is currently still a 32bit application). A detailed description of the purpose of these files will follow.
  • In the %CVB%\Lib directory only the header/wrapper files for C++, Delphi and .Net persist on the Win64 platform. The header files for VB6 have been left out because this language will definitely not support the generation of native 64 bit binaries. The .Net languages are supposed to use the wrapper files located in %CVB%\Lib\Net.

The Wow6432 Folder

When developing for Win64 with Visual Studio or Delphi XE2 one has to keep in mind that the entire Development Environment is still a 32 bit process. This has consequences for development as well as debugging, as 32 bit binaries and 64 bit binaries generally cannot be mixed in the same process. To work around this 32/64 bit boundary during debugging Microsoft and Embarcadero have effectively implemented the debugging of 64 bit binaries as remote debugging, i.e. the process that is being debugged and the debugger itself are being kept in separate processes.

For development the 32/64 bit boundary becomes important when working with components that are being used in the GUI designers of Visual Studio, namely ActiveX controls or User Controls, that are dependent on 64 bit binaries. This is the case with the CVB ActiveX controls: The *.ocx* files have been compiled for Win64 and therefore cannot be used directly in Visual Studio. The workaround in this case consists of providing these components in two versions: One that has been compiled for Win32 (that will be visible and available in Visual Studio and Delphi XE2) and one that has been compiled for Win64 that will be used when running the application.

With CVB, of course the Win64 versions of our ActiveX controls are located in the %CVB% folder of your installation, while the folder %CVB%\Wow6432 folder contains their 32 bit counter parts and the dependencies required to instantiate them. So, whenever a CVB ActiveX control is dropped onto a form in the Visual Studio or Delphi GUI designer, the control that is instantiated actually comes from the folder %CVB%\Wow6432.

It is important to note that the ActiveX controls in this folder are not identical to those installed on Win32! Their type library has been modified to resemble that of the 64bit builds in order to accommodate cross platform development (refer also this section and the chapter on portable code) and is different from that of our Win32 ActiveX controls. To emphasize this, a _wow64 has been appended to the file name. The ActiveX controls thus marked are only intended to be used at design time and are not suitable to run a 32 bit binary on a Win64 operating system properly!

In addition to the aforementioned ActiveX controls, the Wow6432 folder also contains a sub folder named Visual C++ OCX Wrappers. This sub folder contains C++ wrappers for all the ActiveX controls that ship with the Win64 version of CVB. Those files are by and large almost identical to the wrapper files that Visual Studio generates when adding an ActiveX control to a MFC application and generating a member variable for it. However, the Visual Studio wizard responsible for the generation of these files does not generate proper IDispatch callers for properties or functions that use 64 bit numerical types. Therefore all the wrapper files generated by the “Add member variable” wizard will either need to be modified accordingly or be replaced by the files located in the Visual C++ OCX Wrappers folder. The chapter on portable code shows the modifications in more detail.

Common Vision Blox on Linux x64

Directory Structure

When porting CVB to the Linux platform, one of the goals was to integrate CVB as harmonically as possible into this operating system, that looks and feels a lot different from Windows. So instead of re-using the directory tree that is built on the Windows platforms we decided to come up with a new structure that follows the File Hierarchy Standard v. 2.3.

Therefore, on a Linux system the CVB installation is located in the folder /opt/ and its (packet dependant) subfolders:

Folder Content
/opt/ base folder of the CVB installation; empty by default except for the subdirectories listed below
/opt/cvb/bin folder for standalone applications (e.g. configuration utilities, GenICam Browser) and compiled tutorials
/opt/cvb/doc contains the documentation for CVB in compiled HTML format (requires a tool like kchmviewer, gnochm or xchm to read)
/opt/cvb/drivers location for CVB's video interface drivers
/opt/cvb/include contains the C++ header files for CVB (only C++ is supported on the Linux platform); add this location to your compiler's include paths
/opt/cvb/lib folder holding the shared object files for CVB; this location has been added to the system's linker cache through the file /etc/ld.so.conf/libcvb.conf and should be added to your compiler's linker paths
/opt/cvb/tutorial holds the source code of the tutorial applications that ship with CVB for Linux

To make version switches easier, a symbolic link /opt/cvb pointing to /opt/cvb-{MM.mm.sss} is added to the /opt directory. All environment variables and references like the dynamic linker cache use this symlink. Whenever CVB is updated in the future, you may simply bend the symbolic link to the newer version.

In addition to the core CVB installation directory there are a few more folders that contain dependencies or configuration data:|

Folder Content
/etc/opt/cvb location for driver configuration files and license information files
/var/opt/cvb folder hierarchy of the GenICam library that is being used by CVB

Differences Between CVB DLLs and CVB SOs

The shared object files shipped with CVB for Linux contain almost the same set of functions and (more importantly) use the same function interface as the DLLs on the Windows platforms. Where functions have been left out, this happened simply because the necessary underlying infrastructure was not available on Linux (for example the function ImageToDC expects a Windows device context handle and is therefore not available).

CVB Type System and Breaking Changes

This is an overview of the type system depending on the operating system used as well as some breaking changes with new versions.

Type System and Breaking Changes with:

C++

New Type System for CVB's DLL Interface

With CVB 2011 a new type system has been introduced for the DLL interface of Common Vision Blox, with the aim of being able to provide and use the same header files for the Win32, the Win64 and the Lin64 platform. Prior to CVB 2011, the header files for the CVB DLLs have mostly been using the compilers' built-in types like int, long etc. in the functions' signatures. This was working well enough because these built in types always had a fixed size and meaning on the Win32 platform.

With Win64 and Lin64 entering the image, things have gotten slightly more complex:

  • Wherever we are looking at memory offsets, we now need a 64 bit value type on Win64, while on Win32 a 32 bit value type was and is still sufficient
  • While C++'s long on Win64 still has the same meaning as on Win32, the compilers on Lin64 typically treat long as a 64 bit integer value
  • Some types that are generally available on the Win32 platform and that have been used in CVB in the past are not usually defined on the Lin64 platform (e.g. HRESULT, GUID)

To compensate for these effects, we have come up with a type system that now replaces the use of the built-in types in the CVB header files. The significant definitions are all located at the beginning of iCVCImg.h, where pre-processor statements branch into the Win32/Win64 and Lin64 sections. The basic concept was to define and use the new types according to what they stand for instead of simply fixing the bit size of those types for the old and new platforms:

Type sizeof Win32 sizeof Win64 sizeof Lin64 Rationale
cvbbool_t 4 4 1 Used for Boolean values and results. For backward compatibility this maps to BOOL on Win32 and Win64 instead of the built-in type bool.
cvbdatatype_t 4 4 4 Represents a CVB image plane's data type identifier bit field as returned by the ImageDatatype function and used by CreateGenericImageDT.
cvbdensity_t 4 4 8 Represents a search density as used by the ScanImage/ScanPlane functions. Valid values range from 0 to 1000.
cvbdim_t 4 4 8 Represents an x, y or z coordinate in pixels/planes.
cvblicres_t 4 4 4 Result type for the (obsolete!) functions GetLicenseInfo and GetSerialNumber.
cvbres_t 4 4 4 Return type used by most CVB functions outside the CVCImg.dll. This type is interpreted similar to the Windows HRESULT: The most significant bit indicates an error condition, the remaining bits indicate the nature of the error (which is usually one of the values defined in CVCError.h).
cvbval_t 4 4 8 Generic integer value type where the actual amount of bits in the parameter is insignificant for the purposes where this type is being used.
cvbint64_t 8 8 8 Integer value type that is guaranteed to be 64 bits wide.
cvbuint64_t 8 8 8 Unsigned integer value type that is guaranteed to be 64 bits wide.
cvbint32_t 4 4 4 Integer value type that is guaranteed to be 32 bits wide.
cvbuint32_t 4 4 4 Unsigned integer value type that is guaranteed to be 32 bits wide.
cvbint16_t 2 2 2 Integer value type that is guaranteed to be 16 bits wide.
cvbuint16_t 2 2 2 Unsigned integer value type that is guaranteed to be 16 bits wide.
cvbint8_t 1 1 1 Integer value type that is guaranteed to be 8 bits wide.
cvbuint8_t 1 1 1 Unsigned integer value type that is guaranteed to be 8 bits wide.
cvbguid_t 16 16 16 Regular Universally Unique Identifier.

Platform-Polymorphic Types

Of course there are occasions where it is necessary to have a type that is precisely 32 bits wide on the 32 bit platform and 64 bits wide on the 64 bit platforms – think e.g. of the VPAT, where the offset entries can (and for compatibility reasons should) continue to be 32 bits wide on Win32 but where they should rather have 64 bits on Win64 and Lin64. Luckily, the C++ standard already provides us with these types once the header stddef.h has been included in the form of the three types size_t, uintptr_t and intptr_t. Where appropriate, we have substituted long/int by these standard types rather than defined our own version of them.

Breaking Changes

While we did manage to achieve binary compatibility of the CVB DLLs between CVB 10.x and CVB 2011 on Win32, we did have to introduce some changes to function signatures that will break backward compatibility on the compiler level. In other words: Some applications will need to be modified slightly before they will compile without errors with the headers shipped with CVB 2011.

The affected functions are:

  • AnalyseXVPAT, AnalyseYVPAT and GetLinearAccess (iCVCUtilities.h)
    These functions return memory increments by reference, and in response to the requirements of the 64 bit platforms the output parameters' types have changed from long* to intptr_t*. Please update the types used in your source code accordingly.
  • Callbacks TFLine, TFPixelUnary, TFPixelBinary (iCVCImg.h)
    The return type of these callbacks has changed from long to cvbbool_t because the original use of long here was ill-considered as, internally, the return type has always been evaluated in terms of a Boolean result. In order to pass the compiler's type checks, the callbacks defined in your code need to be switched to cvbbool_t.

These examples refer to the Image Manager only. There may be others in tools or in the Foundation Package, but generally your compiler will point this kind of problems out to you either by means of an error (if even implicit type conversion cannot fix the situation) or a warning (make sure to switch on Level 4 warnings and 64bit portability warnings in order to be alerted to all potential conflicts).

.Net

All the .Net DllImport wrappers for CVB have been recompiled for the CVB 2011 release using the “Any CPU” setting of the C# compiler. The aforementioned changes to the C++ DLL interface have been taken into account; therefore the newly built wrappers will be identical on the Win32 and the Win64 release of CVB.

Furthermore, if you built a .Net application based on the CVB managed wrappers with the “Any CPU” setting, it will be possible to run the same assembly with the same wrapper DLLs on the Win32 as well as the Win64 platforms.

Shared Objects

One of the concepts customers frequently seem to struggle with when programming with CVB is that of reference counted objects. In CVB, objects that may potentially be used in several locations of an application and/or in several threads have been given a reference count that – when used properly – allows the object to determine its own lifetime and manage object disposal.

Use of that reference count however will easily and invariably sooner or later lead to either a memory leak or to access violations. The .Net runtime provides two features that allow us for the first time to offer objects that automatically handle their reference count properly:

  • The CLR itself maintains a reference count of the managed reference objects (which is required for the garbage collector to do a reliable job)
  • The CLR allows for the use of objects across programming language boundaries

We have made use of that and implemented several new objects that can manage their lifetime autonomously rather than relying on the user to call ReleaseObject/ShareObject. These objects may be used as a substitute for their “classic” counterparts as they are implicitly convertible. Where CVB functions take one of the old types (see table) as a ref or out parameter, an overload has been added to accept its shared counterpart as a ref or out parameter.

Old “blunt” type new shared type
Cvb.Image.IMG Cvb.SharedImg
Cvb.Image.OBJ Cvb.SharedObj
Cvb.Image.PIXELLIST Cvb.SharedPixelList
Cvb.GenApi.NODE Cvb.SharedNode
Cvb.GenApi.NODEMAP Cvb.SharedNodeMap

We strongly recommend using the shared object types when starting a new application.

Note that the old types have changed as well: Prior to CVB 2011 they were designed as value types and have now be changed to be reference types. Where necessary, update your code accordingly.

VPAEntry

Similar to C++, the components of the VPAEntry structure had to change from pure 32 bit values to platform-polymorphic IntPtr values. As you cannot calculate with IntPtr values directly, be prepared for using lots of typecasts where VPAT operations are involved and make sure to prefer System.Int64 over System.Int32 when doing so, as you might otherwise accidentally cast away the uppermost 32 bits of a 64 bit value (“pointer truncation”).

Node Call-backs and NodeMap Call-backs

As mentioned before, not only have the new shared objects been introduced (see table previously in this chapter), but the underlying “blunt” types also changed: Previously they were value types, and starting with CVB 2011 they have become reference types. In most cases this does not really affect a customer's code because all the calls into unmanaged libraries have been adapted accordingly. However there is one situation for which no workaround exists that does not break backward compatibility and that is when the two call-back types Cvb.GenApi.TFNode and Cvb.GenApi.TFNodeProc are involved: To reproduce the correct behaviour we had on the value type versions of Cvb.GenApi.NODE and Cvb.GenApi.NODEMAP it was necessary to change the signature of those two call-backs to accept System.IntPtr parameters instead of Cvb.GenApi.NODE and Cvb.GenApi.NODEMAP. Inside the callbacks, of course the respective objects are easily created with new Cvb.SharedNode(IntPtr) or new Cvb.SharedNodeMap(IntPtr) calls.

ActiveX Controls

The Type Library Conundrum

When programming for Win64 and Win32 with the CVB ActiveX controls, you will stumble across one obstacle that will affect C++, Delphi and .Net programmers alike: Practically all CVB ActiveX controls at some point map handles to properties or function parameters of type long. On the Win32 platforms this did not hurt, as handles and long are both 32 bits wide. For the Win64 platforms, however, handles are supposed to be 64 bits wide.

The best workaround for this was to use the __int3264 MIDL type for these properties. When compiling the CVB ActiveX controls for Win32 this type maps to long, when compiling for Win64 it becomes a __int64 in the ActiveX control's type library. That way, the compiler generates ActiveX controls that have appropriate type libraries for their target systems, but unfortunately the type library needs to be different between the Win32 and the Win64 version of the ActiveX control.

This has consequences for developers using the ActiveX control because usually a development environment uses the ActiveX control's type library to generate a wrapper class for the object. If the type library differs between the Win32 and the Win64 then this means that the wrapper classes will differ as well – which makes it difficult to write portable code. To make things worse, the wizard that generates the C++ ActiveX wrapper classes cannot handle __int64 properties correctly.

The C++ Solution

To alleviate the situation we have provided modified wrapper classes for C++, based on what the Visual Studio wizard generates. These files are located in the folder %CVB%\Wow6432\Visual C++ OCX Wrappers. Simply replace the files that the Visual Studio wizard generated with these modified files and you will be able to use the same source for the Win32 and Win64 version of your application. You might need to modify the class names as the Visual Studio wizard by default appends an ordinal number to the class name, which has been omitted in our modified wrappers.

C++ is affected by yet another source of trouble with three ActiveX events on the Display OCX (UserPaint) and the DigIO OCX (Listener, Toggler). These events pass handle/pointer types in their signature, so they again need to pass 4 bytes on the 32bit platform and 8 bytes on the 64bit platform. In C++ the handlers for ActiveX events are generated at design time and (unlike with .Net) are not part of the ActiveX wrappers. This means that whenever generating a handler for one of these three events, you will need to use pre-processor switches to generate the proper statements for the target platform. For the UserPaint event this would like something like this:

BEGIN_EVENTSINK_MAP(CMyDlg,CDialogEx)
#ifdef_WIN64
ON_EVENT(CMyDlg,IDC_CVDISPLAYCTRL1,15,CMyDlg::UserPaintCvdisplayctrl1,
VTS_I4VTS_I4VTS_I8VTS_BOOLVTS_I8)
#else
ON_EVENT(CMyDlg,IDC_CVDISPLAYCTRL1,15,CMyDlg::UserPaintCvdisplayctrl1,
VTS_I4VTS_I4VTS_I4VTS_BOOLVTS_I4)
#endif
END_EVENTSINK_MAP()
voidCMyDlg::UserPaintCvdisplayctrl1(longID,longNumVertices,intptr_tVertices,
BOOLDragging,intptr_thDC)
{
//TODO: Add your message handler code here
}

The Delphi Solution

As mentioned previously, Delphi differs from Visual Studio in that it generates the ActiveX wrappers only once, the moment they are added to the Development Environment's toolbar. Programs that use one of these ActiveX controls can then simply link the pre-generated wrapper. During wrapper generation Delphi also makes a small mistake (or misinterpretation, depending on how you look at it) when it interprets arguments of type long* (MIDL) as var LongInt (Delphi) in method signatures. In most cases this interpretation fits the use case, however for example the Display OCX uses parameters of type long* to pass actual pointers to the OCX which contradicts the var LongInt approach. Therefore CVB 2011 comes with a set of modified wrapper files to work around this issue. These are located in the folder %CVB%\Lib\Delphi.

The .Net Solution

When creating a .Net application, Visual Studio frequently re-generates the ActiveX wrappers that have been generated by aximp and tlbimp. Manually modifying these files is partly possible, but with Visual Studio redoing them on each project build this is a tedium. Therefore we suggest another approach: When building your application on either Win32 or Win64 simply use the ActiveX wrappers that have been generated by Visual Studio as they are. This means that on Win32 the Image property will have type System.Int32 and on Win64 the Image property will have type System.Int64. Of course this means that when you ship your application for Win32, you will need to ship it with the ActiveX wrappers generated on the Win32 platform – and likewise with Win64.

In your application you will typically convert between the Image property and variables of either Cvb.Image.IMG or (recommended) Cvb.SharedImg. If you route the Image property through a variable of type System.IntPtr you're on the safe side: You can write platform independent code and your assembly will be usable on Win32 as well as on Win64 – only the wrapper DLLs (AxInterop.<Control Name>.dll and Interop.<Control Name>.dll) will need to match the operating system. The easiest way to get a matching wrapper DLL for the system on which you are deploying is probably to copy them from any of the .Net Tutorials that come with CVB.

To sum it up: Rather than writing e.g.

public void ProcessImage(Cvb.Image.IMGimg)
{
//…
}
private void cvImg_ImageUpdated(object sender, EventArgs e)
{
ProcessImage(Cvb.Image.ToCvbIMG(cvImg.Image));
}

you should code like this:

public void ProcessImage(Cvb.SharedImgimg)
{
//…
}
private void cvImg_ImageUpdated(object sender, EventArgs e)
{
ProcessImage(new Cvb.SharedImg(cvImg.Image));
}

This short sample assumes that cvImg is an object of type AxCVIMAGELib.AxCVimage.

Portable Code

In this chapter you will find some additional hints for:

Building new applications from scratch:

Migration of existing applications:

Building Applications From Scratch

C++

When starting a new application, using the newly introduced type system in the DLL interface is recommendable as this will make ports to other platforms a lot easier. When using ActiveX controls, do not forget to replace the faulty C++ wrappers generated by Visual Studio with the ones provided in %CVB%\Wow6432\Visual C++ OCX Wrappers.

In case you are planning on targeting Linux later on it is a good idea to either use a GUI toolkit that is available for both platforms right from the beginning or to keep your user interface code as separate from your image processing code as possible to make the necessary switch to a different GUI toolkit easier. ActiveX controls are a technology that is not available on the Lin64 platform and should therefore not be used at all in applications that are intended to be portable. Note that for C++/CLI projects in Visual Studio 2010 the AnyCPU tweak for aximp and tlbimp described in the migration section must also be applied.

.Net

With newly created .Net applications there is actually not much attention to be paid to Win32/Win64 portability. The main issue here is to keep track of which platform the ActiveX wrappers have been created on (if your application uses ActiveX controls); a mismatch however will immediately lead to an exception, is therefore fairly easy to identify and will probably never go unnoticed. Keeping the coding hints from earlier in mind and using the new shared objects will help avoid improper reference count handling and (for VB.Net users) perilous assignments of 64 bit values to 32 bit variables. If you use Visual Studio 2010 please note that the AnyCPU tweak described in the migration section must be applied to a project file before it will be possible to generate and run applications targeted to the .Net 4.0 framework.

Migration of Existing Applications

C++

The types used in the DLL interface are practically identical between Win32 and Win64 (of course with the pointer types being 64 bits wide, but that is handled implicitly as long as no conversion between pointer types and integer types happens in your code). So for the DLL interface all that needs to be done is to adapt your code to the breaking changes that have been made to the DLL interface.

With the ActiveX controls, there is the added complication of the differing type library (and therefore the need for different wrapper classes on the different architectures). You should, at any rate, replace the C++ wrappers for ActiveX controls that have been generated for Win32 with the ones found in the %CVB%\Wow6432\Visual C++ OCX Wrappers folder: If you don't, the old Win32 wrappers will only marshal 4 bytes for each Image pointer through the OCX's IDispatch interface even if compiled for x64 without even raising an error. This will work for quite a while (while memory consumption in a process is still low, the upper 32 bits of pointers on Win64 tend to be zero…), but sooner or later this will lead to intermittent problems that will be very challenging to debug.

If your application uses the Display's UserPaint event or the DigIO Control's Listener or Toggler event then make sure to adapt the event signature and the MFC macros for event marshalling according the description in the section about ActiveX controls. Once these changes have been made to a project, it is ready for x64 compilation. Transfer it to your x64 development machine if you have not already done so and add "x64" debug and release configurations to the Visual Studio project (you can simply base all the settings on the corresponding “Win32” platform configurations). Note that even though you can run the Win32 build result of some applications on the x64 platform this is not a supported configuration and unlikely to work properly for more than a few minutes! It is not strictly necessary to adapt your project to the new type system outlined earlier for it to compile and run on x64. If, however, you want to target Linux at some point, a switch to the new type system will be inevitable.

.Net

With the .Net languages, migrating a project is no more difficult than with C++. The first step will be to add the newly built DllImport wrappers to your project references. Doing so will make the compiler point out the locations of breaking changes to you, so fixing those will be fairly straightforward.

What requires more attention is the handling of the ActiveX controls. Make sure you do the port on a Win64 development system – otherwise the ActiveX wrappers will be built versus the wrong (Win32) type library. Remove your projects' obj and bin folders – this will force Visual Studio to rebuild the ActiveX wrapper DLLs. Note that ActiveX Control usage will not work when using .Net 4.0 as the targeted framework version (for details see the next paragraph)! When using C#, once the ActiveX wrappers have been recreated all problematic property assignments from 64 bit integer values to 32 bit integer values will be pointed out by the compiler (C# does not support automatic conversion from System.Int64 to System.Int32). VB.Net unfortunately is less strict here, and it is highly recommended to search your code for such assignments and correct them.

Consider upgrading your code to use the new shared object types introduced in CVB 2011. For portability this is not a requirement, but these types go a long way to helping you make sure the CVB reference count is being used properly. If you migrated your application to Visual Studio 2010 and want to target the .Net Framework 4.0 there is yet another pitfall waiting for you: By default, the ActiveX wrappers generated by Visual Studio 2010 with the .Net Framework 4.0 toolset will be specific to the platform of the ActiveX control for which they have been generated (in our case, the “_wow” versions of the CVB ActiveX controls). In other words: The thus generated wrappers will be targeting the Win32 platform and when trying to load them into a Win64 application, the .Net Runtime will throw a System.BadImageFormatException. In order to coerce Visual Studio 2010 into generating “Any CPU” wrappers with the .Net Framework 4.0 toolset (namely aximp and tlbimp) it is necessary to manually modify the csproj or vbproj file:

  • Locate all the PropertyGroup nodes containing a Condition entry of the form '| '=='Release| AnyCPU' (in a typical project there would be 2 of these nodes: One for Debug| AnyCPU and one for Release| AnyCPU).
  • For all those nodes where the condition states AnyCPU add an entry <PlatformTarget>AnyCPU<\/PlatformTarget> With these changes applied, the automatically generated ActiveX wrappers will be loadable into an AnyCPU application running on Win64. The same change is also required for C++/CLI projects, which, by default, always target the .Net Framework 4.0.|

Hello CVB

In the following sections, step by step instructions will be given for some supported development environments to guide you through the creation of a

→ very basic application that simply acquires and displays live images.

For simplicity, these applications mostly use ActiveX controls to achieve their goal. For examples leading beyond the fairly limited scope of these "Hello World" type applications the reader is encouraged to have a peek at the several dozen tutorials /example applications that ship with Common Vision Blox. Refer %CVB%\Tutorial directory.

Visual C++/MFC

1) Start the Visual Studio development environment and choose New from the File menu. On the Project types dialog select the Visual C++ programming language and create a new MFC Application. Enter VCMFC_DialogApplication as the project name:


2) Confirm your input by clicking OK.
In the next dialog select the Dialog based option as the application type (if you are interested in single document or multiple document applications: many of the steps that follow are almost directly transferable from the dialog application to an SDI or MDI applications views).


Change the automatically generated Class name to e.g. CVCMFC_DialogApplicationDlg:


3) Confirm your inputs and the default settings in the next dialog box(es) by clicking Finish.

4) If this has not yet been done, it is now necessary to add the Common Vision Blox ActiveX components to the Visual Studio Toolbox.
This step is only necessary the first time you use these components. From the Tools menu choose Choose Toolbox Items (also accessible through the tool box context menu). This will open the Customize Toolbox dialog box with a list of all registered ActiveX Components will appear:


Check all the components you want to add to the Toolbox (the Common Vision Blox components' naming pattern is Common Vision ... Control, for the rest of this section you will at least need Display and Image Control) and press OK. This will persistently add the selected components to the Toolbox - next time you create a new project with Visual Studio the Common Vision Blox controls will already be available in Visual Studio's Toolbox.


5) Now the Display and Image Control need to be inserted into the dialog.
Select Visual Studio's Resource View, and double-click on the dialog IDD_VCMFC_DIALOGAPPLICATION_DIALOG. This will open the Visual C++ dialog editor:


6) Delete the automatically generated buttons OK, Cancel and the TODO: ... Text label.
Then add one instance of the Image Control and one Instance of the Display Control to the dialog by selecting the respective control in the Toolbox and dropping it on the dialog.


7) It is possible to specify an image to be loaded immediately when the ActiveX Control is being instantiated.
To do this, open the control's general property page and click the Browse button to select an image or driver file. For the moment, use the file Clara.bmp from the %CVB%Tutorial directory.


8) To interact with the Image and Display Control your program now needs member variables for each of them.
To add a member variable for any control simply right click on it in the dialog editor and select Add Variable from the context menu. This will open a dialog where type- and variable names can be edited as well as the names of the wrapper files that Visual Studio will automatically generate for ActiveX Controls:


Enter m_cvImg as variable name, change the variable type from CCvimagectrl1 to CCvimagectrl and change the header and source file names to cvimagectrl.h and cvimagectrl.cpp (the latter two are not strictly necessary, but will make the transition to 64 bit easier). Repeat these steps for the Display Control, using the names m_cvDisp, CCvdisplayctrl and cvdisplayctrl.h/.cpp.

x64 builds:
After closing the "Add Member Variable Wizard" please overwrite the wrapper files (cvimagectrl.h/.cpp, cvdisplayctrl.h/.cpp) that have been generated with the files found in %CVB%\Wow6432\Visual C++ OCX Wrappers. This is required because the automatically generated ActiveX wrappers for Visual C++ contain errors that make them unusable in a 64 bit build. The wrappers found in the %CVB%\Wow6432\Visual C++ OCX Wrappers folder are suitable for 32 as well as 64 bit builds.

9) The Common Vision Blox API does not support unicode characters (all functions that accept or return a string only accept a pointer to a zero terminated ANSI character string).
Visual C++ however promotes the use of the types LPTSTR and LPCTSTR throughout the Windows SDK - and those types by default map to wchar_t* and const wchar_t*. Therefore it's convenient to tell Visual Studio not to use unicode - in this case, LPTSTR and LPCTSTR map to char* and const char*:


This is not strictly necessary: It is possible to use Common Vision Blox in an application that uses unicode. However, this adds the inconvenience of having to convert strings before/after calls to Common Vision Blox functions - something we did not want to clutter the tutorials with.

10) You now have a fully functional MFC dialog application that contains a Common Vision Blox Display and Image Control.
The Image Control even loads an image when the application starts - all that is required to make this image visible now is to establish a connection between the Display and the Image Control. This is done by copying the handle value in the Image Control's Image handle to the Display Control's Image handle. To do that, open the file VCMFC_DialogTestApplicationDlg.cpp and look for the OnInitDialog function. At the end of that function simply add the line

m_cvDisp.SetImage(m_cvImg.GetImage());

11) Compile and run the application. It should come up with a Common Vision Blox display that shows the bitmap from the file Clara.bmp:


12) To take the application one step further, we now add the capability for displaying live images.
First of all, instead of loading Clara.bmp, the program now needs to load a video interface driver, for example the GenICam.vin (make sure the driver is configured correctly with the CVB GenICam Browser); if you want to use a different vin driver simply substitute its name in the code below). To do that, simply add another line before the one that has been added in step 10:

m_cvImg.LoadImage("%CVB%\\Drivers\\GenICam.vin");
m_cvDisp.SetImage(m_cvImg.GetImage());

13) To be able to start and stop live acquisition, add a check box to the dialog and name it "Grab"...


... then add a member variable named m_cbGrab of type Cbutton:


14) To react to state changes of the check box, we'll need to provide a handler routine for the checked change event.
To that end, double click the newly added check box. This will open the routine OnBnClickedCheck1 in the source code editor. Modify this routine to look as follows:

void CVCMFC_DialogApplicationDlg::OnBnClickedCheck1()
{
// TODO: Add your control notification handler code here
m_cvImg.SetGrab(m_cbGrab.GetCheck());
}

15) The last thing to implement now is an adequate reaction to the acquisition of a new frame.
The Image Control reports newly acquired images by means of the ImageSnaped event that will be raised every time the camera has delivered a new image. To react to the ImageSnaped event select the Image Control on your form, then change the Properties Window to show the control's events. Simply double click the empty cell next to ImageSnaped to generate a new handler for the ImageSnaped event.


In the new event handler's source simply add a call to the Display Control's Refresh method:

void CVCMFC_DialogApplicationDlg::ImageSnapedCvimagectrl1()
{
// TODO: Add your message handler code here
m_cvDisp.Refresh();
}

16) Now compile and run the application.
You can:

  • start/stop live acquisition by checking/unchecking the Grab check box and the
  • Display will show the live image from the camera.
  • It is also directly possible to use the interactive zoom of the Display Control.


Refer further code examples in the CVB Tutorials (%CVB%Tutorial folder).

C-Sharp

1) Start the Visual Studio development environment and choose New from the File menu. On the Project types dialog select the C# programming language and create a new Windows Forms Application. Enter CSNet_FirstCVBApplication as the project name:


2) Confirm your input by clicking OK.

3) If this has not yet been done, it is now necessary to add the Common Vision Blox ActiveX components to the Visual Studio Toolbox.
This step is only necessary the first time you use these components. From the Tools menu choose Choose Toolbox Items (also accessible through the tool box context menu). This will open the Customize Toolbox dialog box with a list of all registered ActiveX Components will appear:


Check all the components you want to add to the Toolbox (the Common Vision Blox components' naming pattern is Common Vision ... Control, for the rest of this section you will at least need Display and Image Control) and press OK. This will persistently add the selected components to the Toolbox - next time you create a new project with Visual Studio the Common Vision Blox controls will already be available in Visual Studio's Toolbox.


4) Add one instance of the Image Control and one Instance of the Display Control to the form by selecting the respective control in the Toolbox and dropping it on the form.


5) It is possible to specify an image to be loaded immediately when the ActiveX Control is being instantiated.
To do this, open the control's general property page and click the Browse button to select an image or driver file. For the moment, use the file Clara.bmp from the %CVB%\Tutorial directory.


6) You now have a fully functional Windows Forms application that contains a Common Vision Blox Display and Image Control.
The Image Control even loads an image when the application starts - all that is required to make this image visible now is to establish a connection between the Display and the Image Control. This is done by copying the handle value in the Image Control's Image handle to the Display Control's Image handle (see description of ActiveX Controls). To do that, double click on the form's background. This will insert a new handler function for the Form_Load event and open it in the source code editor. Modify the event handler to establish the connection between Display and Image Control.

private void Form1_Load(object sender, EventArgs e)
{
// set image to display
axCVdisplay1.Image = axCVimage1.Image;
}

7) Compile and run the application.
It should come up with a Common Vision Blox display that shows the bitmap from the file Clara.bmp:


8) To take the application one step further, we now add the capability for displaying live images.
First of all, instead of loading Clara.bmp, the program now needs to load a video interface driver, for example the GenICam.vin (make sure the driver is configured correctly with the CVB GenICam Browser; if you want to use a different vin driver simply substitute its name in the code below). To do that, simply add another line before the one that has been added in step 6:

axCVimage1.LoadImage(@"\%CVB\%\Drivers\GenICam.vin");
axCVdisplay1.Image = axCVimage1.Image;

9) To be able to start and stop live acquisition, add a check box to the dialog...


... change its Text property from "Checkbox1" to "Grab", the Name from Checkbox1 to CheckBoxGrab and then double-click the check box. This will insert an event handler for the control's default event (CheckedChanged) to your program and open it in the source code editor.

private void CheckBoxGrab_CheckedChanged(object sender, EventArgs e)
{
// set grab status
axCVimage1.Grab = CheckBoxGrab.Checked;
}

10) The last thing to implement now is an adequate reaction to the acquisition of a new frame.
The Image Control reports newly acquired images by means of the ImageSnapped event that will be raised every time the camera has delivered a new image. To react to the ImageSnapped event select the Image Control on your form, then change the Properties Window to show the control's events. Simply double click the empty cell next to ImageSnaped to generate a new handler for the ImageSnapped event.

![](cvbmain_DotNet_Add_ImageSnaped_Event](f0x5vc42.064.png)

In the new event handler's source simply add a call to the Display Control's Refresh method:

private void axCVimage1_ImageSnaped(object sender, EventArgs e)
{
// refresh display
axCVdisplay1.Refresh();
}

11) Now compile and run the application.
You can:

  • start/stop live acquisition by checking/unchecking the Grab check box and the
  • Display will show the live image from the camera.
  • It is also directly possible to use the interactive zoom of the Display Control.


Refer further code examples in the CVB Tutorials (%CVB%Tutorial folder).

VB.Net

1) Start the Visual Studio development environment and choose New from the File menu. On the Project types dialog select the VB.Net programming language and create a new Windows Forms Application. Enter VBNet_FirstCVBApplication as the project name:


2) Confirm your input by clicking OK.

3) If this has not yet been done, it is now necessary to add the Common Vision Blox ActiveX components to the Visual Studio Toolbox.
This step is only necessary the first time you use these components. From the Tools menu choose Choose Toolbox Items (also accessible through the tool box context menu). This will open the Customize Toolbox dialog box with a list of all registered ActiveX Components will appear:


Check all the components you want to add to the Toolbox (the Common Vision Blox components' naming pattern is Common Vision ... Control, for the rest of this section you will at least need Display and Image Control) and press OK. This will persistently add the selected components to the Toolbox - next time you create a new project with Visual Studio the Common Vision Blox controls will already be available in Visual Studio's Toolbox.


4) Add one instance of the Image Control and one Instance of the Display Control to the form by selecting the respective control in the Toolbox and dropping it on the form.


5) It is possible to specify an image to be loaded immediately when the ActiveX Control is being instantiated.
To do this, open the control's general property page and click the Browse button to select an image or driver file. For the moment, use the file Clara.bmp from the %CVB%Tutorial directory.


6) You now have a fully functional Windows Forms application that contains a Common Vision Blox Display and Image Control.
The Image Control even loads an image when the application starts - all that is required to make this image visible now is to establish a connection between the Display and the Image Control. This is done by copying the handle value in the Image Control's Image handle to the Display Control's Image handle. To do that, double click on the form's background. This will insert a new handler function for the Form_Load event and open it in the source code editor. Modify the event handler to establish the connection between Display and Image Control.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' set image to display
AxCVdisplay1.Image = AxCVimage1.Image
End Sub

7) Compile and run the application.
It should come up with a Common Vision Blox display that shows the bitmap from the file Clara.bmp:


8) To take the application one step further, we now add the capability for displaying live images.
First of all, instead of loading Clara.bmp, the program now needs to load a video interface driver, for example the GenICam.vin(make sure the driver is configured correctly with the CVB GenICam Browser; if you want to use a different vin driver simply substitute its name in the code below). To do that, simply add another line before the one that has been added in step 6:

AxCVimage1.LoadImage("%CVB%\\Drivers\\GenICam.vin");
AxCVdisplay1.Image=AxCVimage1.Image;

9) To be able to start and stop live acquisition, add a check box to the form...


... change its Text property from "Checkbox1" to "Grab", the Name from Checkbox1 to CheckBoxGrab and then double-click the check box. This will insert an event handler for the control's default event (CheckedChanged) to your program and open it in the source code editor.

Private Sub CheckBoxGrab_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBoxGrab.CheckedChanged
' set grab status
AxCVimage1.Grab = CheckBoxGrab.Checked
End Sub

10) The last thing to implement now is an adequate reaction to the acquisition of a new frame.
The Image Control reports newly acquired images by means of the ImageSnapped event that will be raised every time the camera has delivered a new image. To react to the ImageSnapped event select the Image Control on your form, then change the Properties Window to show the control's events. Simply double click the empty cell next to ImageSnaped to generate a new handler for the ImageSnapped event.


In the new event handler's source simply add a call to the Display Control's Refresh method:

Private Sub AxCVimage1_ImageSnaped(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AxCVimage1.ImageSnaped
' refresh display
AxCVdisplay1.Refresh()
End Sub

11) Now compile and run the application.
You can:

  • start/stop live acquisition by checking/unchecking the Grab check box and the
  • Display will show the live image from the camera.
  • It is also directly possible to use the interactive zoom of the Display Control.


Refer further code examples in the CVB Tutorials (%CVB%Tutorials folder).

Getting Started with CVB.Net

The CVB.Net API is a new object oriented wrapper for the CVB SDK. It has been designed to harmoniusly integrate into the .Net API and makes leveraging the abilities of CVB for complex applications written in one of the .Net/CLR languages easier than the classic C-like API. CVB.Net has been built versus the .Net 4.0 runtime and therefore requires Visual Studio 2010 or higher to work with.

For GUI integration, CVB.Net offers two options:

  • Windows Forms applications may use the component Stemmer.Cvb.Forms.Controls.Display on their forms.
    This component is based on the CVCDisp.dll of CVB and integrates all the features that the CVDisplay.ocx offers, including integration of *.opi plug ins.
  • WPF applications can use the Stemmer.Cvb.Wpf.Controls.Display control which is an IL-implemented display derived from System.Windows.Controls.ItemsControl, capable of displaying any System.Windows.UIElement-derived object as a non-destructive overlay (a few “standard” overlays may be found in the namespace Stemmer.Cvb.Wpf.Overlays).

As long as no platform-specific elements were used, CVB.Net is - with the exception of Stemmer.Cvb.Forms and Stemmer.Cvb.Wpf - compliant with .Net Core 2.0 and may therefore also be used on platforms other than Windows.

Refer following CVB User Forum tutorials:

Getting Started with CVB.Net