Here are instructions for how to set up a Visual Studio project for a new device adapter. For more details on how to write device adapters for Micro-Manager, see Building Micro-Manager Device Adapters. For instructions on how to build existing device adapters in the Micro-Manager subversion repository, see the page on Building MM on Windows.
Setting up a new device adapter project
See the page on Building MM on Windows for how to set up a development environment for Micro-Manager, including Microsoft Visual Studio 2010 Express SP1 and Microsoft Windows SDK 7.1. The following assumes that those instructions were followed.
Method 1: Building using micromanager.sln
micromanager.sln(at the root of the
micromanagersource tree) in Visual Studio.
- In the Solution Explorer (usually at the left of the window), right-click on the Solution (at the top of the list), and choose Add > New Project….
- Choose Win32 Project (under Visual C++ > Win32). Give your
project a Name (this will be your device adapter’s name, so
avoid spaces and use alphanumeric characters, dashes, and
underscores only). Set the Location to either
TestDeviceAdapters/(in theory, it does not matter where you set this). Click OK.
- The Win32 Application Wizard will open. Click Next.
- For Application type, select DLL. Make sure to check Empty Project. Click Finish.
- Your new project should show up in the Solution Explorer.
- From the menu bar, select Tools > Settings > Expert Settings. Notice that three tabs appear at the bottom of the Solution Explorer. Click Property Manager (the rightmost tab).
- Find your project in the Property Manager list. Right-click on
the project and select Add Existing Property Sheet…. Choose
- Repeat the previous step, this time choosing
buildscripts/VisualStudio/MMDeviceAdapter.props. Make sure that the two added property sheets are displayed under each configuration (Debug|Win32 and Release|Win32), with MMDeviceAdapter at the top (= downstream). These property sheets provide various project settings common to all Micro-Manager device adapters.
- Now return to the Solution Explorer by clicking on the leftmost tab at the bottom of the Property Manager.
- Lets add our first source files to the project. Right-click the project, and choose Add > Class…, then C++ Class.
- Enter a class name for your first device, e.g.
MyCamera. Leave the Base class empty for now. After adding the class, close the Add Class window which reappears.
- In my testing, the
MyCamera.cppfiles created in the previous step were blank - although I think they are supposed to contain a skeleton class implementation. In any case, how to actually code device adapters is beyond the scope of this particular page, so lets continue with the project settings.
- Right-click on your project, and choose Properties. This will open the Property Pages. There are lots of settings here; we will first make the minimal changes to get a working device adapter. A later section of this page will describe some more settings in the context of a Micro-Manager device adapter.
- Under Common Properties > Framework and References, click on
Add New Reference…. Scroll down and select
MMDevice-SharedRuntime (not to be confused with
MMDevice-StaticRuntime). Click OK. A list of True/False settings
will show up on the right-hand-side of the window; the default
settings are fine. This setting causes your device adapter to be
linked to the common Micro-Manager device adapter library (built
from the code in the
- Now we will edit some settings under Configuration Properties. When we do so, the settings are only applied to the build configuration and platform selected at the top of the Property Pages window. We only have one platform (Win32) so far, but we want the settings to apply to both configurations (Debug and Release), so choose All Configurations from the Configuration: popup menu (make sure you do this again if you close and reopen the Property Pages).
- Under Configuration Properties > General, set Platform Toolset to Windows7.1SDK.
- Under Configuration Properties > C/C++ > General, set
Warning Level to **
** (which should display **Level4** after clicking **Apply**).
- Under Configuration Properties > C/C++ > Precompiled
Headers, set Precompiled Header to
** (which should display **Not Using Precompiled Headers** after clicking **Apply**).
- By default, the device adapter project will only compile for 32-bit (the Win32 platform). To add the settings for 64-bit (x64 platform), click on Configuration Manager… at the top-left of the Property Pages. Select x64 from the Active solution platform popup. Find your new project in the list. Click on the triangle next to the cell that says Win32, and choose <New…>. Choose x64 for the New platform, and Win32 for Copy settings from. Click OK. Now, in the Configuration Manager table, click the Build checkbox for your project.
- That’s it! Write the code for your device class, and right-click
your project and select Build. If all goes well, your device
adapter DLL should be built as
build/Release/Win32/mmgr_dal_Example.dll(or in the directory corresponding to the selected configuration and platform).
Method 2: Building using a custom solution file
This option may be convenient if you are only working on a single device
adapter and want to avoid seeing a long list of projects (and waiting
for Visual Studio to process them). It also has the advantage that you
don’t need to locally modify the
micromanager.sln file, and can place
all of your device adapter files outside of the
tree, if you wish.
The steps are basically the same as Method 1 (using
except that you will start by choosing File > New > Project…
instead of adding a new project to the existing solution.
Just before the step of adding a reference to MMDevice-SharedRuntime, you will need to perform the following steps:
- Right-click on the Solution at the top of the Solution Explorer and choose Add > Existing Project…). (Make sure to right-click the solution, not the project. The solution contains the project. Alternatively, you can use File > Add > Existing Project….)
- When adding the reference, if MMDevice-SharedRuntime does not show up in the Add Reference list, cancel the adding, right-click on your device adapter project, and choose Unload Project, followed by Reload Project. Then try again to add the reference.
At some point (usually the first time you build or close Visual Studio),
you will be prompted to save the solution file (
.sln). Saving to the
default location (next to the
.vcxproj file) usually works well when
developing a device adapter. Note that the build products are placed in
build directory in the same directory as the solution file.
Visual Studio project properties for Micro-Manager device adapters
Here are some notes on how project properties should be set for Micro-Manager device adapters. They are organized analogously to the hierarchy in the Property Pages window.
Note that the following assumes that you have correctly added the
MMDeviceAdapter.props property sheets (in that
order, so that MMCommon is upstream) to your project (see the earlier
section on setting up new projects).
Framework and References: There should be a single reference, to
MMDevice-SharedRuntime (the static library containing the common device
adapter code in
MMDevice/). The properties for this reference should
be as follows (they are the default settings):
- Copy Local = True
- Copy Local Satellite Assemblies = False
- Reference Assembly Output = True
- Link Library Dependencies = True (this causes the static library to be linked)
- Use Library Dependency Inputs = False (True would link to the MMDevice object files instead of the library)
Advanced note: If, for some reason, your device adapter needs to be
built against the static version of Microsoft’s C Runtime (known as
/MT), rather than the default DLL version (
need to use MMDevice-StaticRuntime instead of MMDevice-SharedRuntime.
This is the case if you are linking against a third-party static library
(not a DLL import library, but a real static library) that was built
against the static C Runtime. See the Runtime Library property below
under C/C++ > Code Generation.
Output Directory, Intermediate Directory, Target Name, Target Extension: These are set by the common property sheets. Make sure your project does not override the defaults.
Platform Toolset: To compile 64-bit code with the free (Express) edition of Visual Studio 2010, this must be set to Windows7.1SDK. This is what the Micro-Manager codebase uses.
Use of MFC, Use of ATL: Device adapters in the official Micro-Manager repository do not make use of MFC or ATL, as it is not available with the free edition of Visual Studio.
Character Set: This should not affect most device adapter projects. For those device adapters that use the Windows Win32 API (discouraged unless strictly necessary), it will determine whether the Win32 functions operate on char strings (Use Multi-Byte Character Set = use ASCII and old-fashioned non-Unicode encodings) or wide char strings (Use Unicode Character Set = use UTF-16). If it is necessary to use Win32 API calls, it is encourage that the device adapter use the versions of the functions with a “A” or “W” suffix, so that build settings do not affect code behavior. Alternatively, the TCHAR mechanism can be used to keep the code neutral with respect to this setting, if care is taken when strings are converted to and from C or C++ strings (char* or std::string). We do not currently have any explicit support for non-ASCII strings.
The options in this section cannot be set in common property sheets and must be set correctly in each project.
Default settings should be fine.
It is best to leave these at their default values, as modifying them will just be confusing in most cases. Use the settings under C/C++ and Linker for setting include and library directories.
C/C++ > General
Additional Include Directories: If you need to include third-party header files, add the directory containing them here. Note that the Boost C++ library (not all modules) is made available by default.
Warning Level: We prefer Level4. Choose
C/C++ > Optimization
Whole Program Optimization: No is recommended. Turning this on can make it more difficult to interpret crash logs (hs_err logs) or crash dumps.
C/C++ > Preprocessor
Preprocessor Definitions: The necessary MODULE_EXPORTS macro is
now provided by the
MMDeviceAdapter.props property sheet, so no
special settings are necessary for most device adapters.
C/C++ > Code Generation
Enable C++ Exceptions: Yes (/EHsc) (the default) is recommended. Do not turn on SEH Exceptions; see this page for why.
Runtime Library: Use the DLL variants (the default). If you need to link against a third-party static library that uses the static (non-DLL) variant, you will need to choose the non-DLL variants here. Avoid this unless actually necessary, because there is a small limit (128) for the number of DLLs built against the static C Runtime that can be simultaneously loaded. Make sure to use the corresponding variant of MMDevice if making the switch (see above under Framework and References).
C/C++ > Precompiled Headers
Precompiled Header: We avoid using precompiled headers to keep the
project organization simple. Select
Linker > General
Output File: The default setting should produce the
prefix if the common property sheets are included correctly.
Additional Library Directories: If linking to a third-party library,
you will need to add the directory containing the
.lib files here.
Link Library Dependencies: Must be set to Yes (=
Linker > Input
Additional Dependencies: If linking to a third-party library, add
the filenames (
Linker > Debugging
Generate Debug Info: Best to set to Yes (/DEBUG) even for release builds.
No settings required. In the past we used a post-build event to copy the product (DLL file) to a different destination, but this is no longer the case with the current build files.