THE Machine Vision Operation System
The perfect platform for vision application development.
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
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:
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.|
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 the common vision blox website. In addition to the hardware abstraction layer, the Image Manager provides functionality for handling image data like
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). 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
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 the common vision blox website).
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.
Refer to www.stemmer-imaging.com for getting in contact.
The most up-to-date download version of Common Vision Blox and the Common Vision Blox CameraSuite and older CVB versions can be downloaded in the 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).
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.
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.
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.
When designing the CVB.Net, CVB++ and CVBpy APIs, the following considerations were the cornerstones for the design decisions:
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:
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:
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.
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.
C-style | CVB.Net | CVB++ | 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 | |||||
CVPolarization.dll | 4 | ||||
etBayerToRGB.dll | |||||
LightMeter.dll ocx | |||||
TextOut.dll | 4 | 4 | 4 | ||
CVCBarcode.dll ocx † | 4 | ||||
CVCBlob.dll ocx | |||||
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
There are several sources for answers to your questions regarding Common Vision Blox:
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 the CVB website 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.su.nosp@m.ppor.nosp@m.t@ste.nosp@m.mmer.nosp@m.-imag.nosp@m.ing..nosp@m.com |
Internet: | Common Vision Blox website forum.commonvisionblox.com |
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:
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.
The Common Vision Blox licensing is describe here.
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 Configuration Guide.
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 :
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 Hardware User Guides.
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.
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:
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 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.
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.
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 the API.
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)
In this chapter you will find a lot of useful hints and background informations regarding the support and use of CVB with compilers.
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.
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:
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.
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.
Image Manager (and thus CameraSuite):
Foundation Package:
Tools:
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:
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
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.
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.
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:
Simply by caching a few values and taking them outside the loop the function executes about 1 to 2 orders faster:
The Common Vision Blox Display Control does have two methods that are inherently incompatible with .Net languages:
To work around this issue, the methods
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.|
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.
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).
Generally all imported functions are defined as follows:
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:
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:
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:
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:
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.
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:
for parameters or
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:
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:
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):
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:
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:
But exactly this implementation would lead to the problem described above. Thus the MarshalAs-attribut for the return value is added:
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:
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:
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:
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:
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.
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.
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:
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.
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 |
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).
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:
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:
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. |
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.
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:
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).
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.
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:
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.
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”).
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.
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.
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:
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.
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.
you should code like this:
This short sample assumes that cvImg is an object of type AxCVIMAGELib.AxCVimage.
In this chapter you will find some additional hints for:
Building new applications from scratch:
Migration of existing applications:
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.
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.
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.
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:
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.
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
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:
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:
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:
16) Now compile and run the application.
You can:
Refer further code examples in the CVB Tutorials (%CVB%Tutorial folder).
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.
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:
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.
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:
11) Now compile and run the application.
You can:
Refer further code examples in the CVB Tutorials (%CVB%Tutorial folder).
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.
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:
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.
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:
11) Now compile and run the application.
You can:
Refer further code examples in the CVB Tutorials (%CVB%Tutorials folder).
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:
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: