Imagix 4D User Guide


Support of Microsoft Visual C++

Type Libraries and #import

Under Microsoft Visual C++, COM type definitions can reside in a type library. These definitions are made available to the source code through the Microsoft-specific preprocessor directive #import, for example:

#import <libraryname.tlb>
A number of file types can include type libraries, and are supported through the MSVC compiler's #import directive. The most common is the type library binary (.tlb). Type libraries can also be contained in object libraries (.olb), executables (.exe) and dynamic link libraries (.dll), as well as files identified by progid or libid, for example:

#import "progid:my.prog.id.1.5"
or
#import "libid:12341234-1234-1234-1234-1234" version("4.0") lcid("9")
Analyzing a .tlh file
When Imagix 4D's source analyzer processes the #import command, it first tries to include the equivalent compiler-generated primary header file. When encountering an #import directive specifying libraryname.tlb or libraryname.exe, the source analyzer will look for a header file named libraryname.tlh.

Such .tlh files are created by the MSVC compiler, and may already exist in your environment. If they don't yet exist, you may choose to run the compiler before loading in your code. For .tlb file types, the compiler will normally generate the corresponding .tlh file. For other types, such as .olb, .exe and .dll files, the .tlh file may or may not be created. The MSVC compiler never generates equivalent .tlh header files for the progid and libid library names, which are also not supported by Imagix 4D's source analyzer. Refer to the Microsoft documentation for further information about this.

For an existing .tlh to be found by Imagix 4D's source analyzer, it needs to be located in an include path specified through the -I and -S options passed to the source analyzer. Normally, the -I and -S options are defined automatically when you create an MSVC Project or MSVC Workspace / Solution data source to load a Visual Studio project. If the .tlh file does exist, but you're getting a warning message, you'll need to add a -I option to specify the directory where the file is located. You can specify the additional -I option in the Options field of the Project tab of the Data Sources dialog.

Often, primary header files (.tlh) contain a #include directive pointing to a secondary header file (.tli), where compiler-generated member functions are defined. If the warning message refers to a .tli rather than a .tlh file not being found, you'll again need to check for the existence of the .tli file, and run the MSVC compiler to try to generate any missing files. In most cases, you can ignore missing .tli files because they don't add information to the Imagix 4D data source.

Analyzing a .inc file
If the .tlh file does not exist or cannot be found, the analyzer next looks for an equivalent .inc file. This is an Imagix 4D specific configuration file that contains definitions for the classes and types in the specified type library. These are definitions similar to what would be found in the .tlh header files. For libraryname.tlb, the source analyzer will search for a .inc file named libraryname.tlb.inc. For libraryname.dll, the file name would be libraryname.dll.inc.

The source analyzer checks for these .inc files in the include path specified through the -I and -S options. Additionally under Linux/Unix, the installation path ../imagix/user/cc_cfg/msvc_lib is checked. If the corresponding .inc file is found, it is analyzed as source code, just like a .tlh header file or a compiler configuration file.

Generating a .inc file
If no .inc file is found, what the source analyzer does next depends on the operating system. Under Windows, if Imagix 4D's source analyzer is unable to find an equivalent .tlh or .inc file, it attempts to process the original .tlb, .olb, .exe or .dll type library file. The source analyzer uses the Windows system call LoadTypeLib() to load the type library. Refer to Microsoft documentation for LoadTypeLib()'s file search process.

If the source analyzer finds the binary type library file, it processes that file and automatically generates a .inc file that contains the class and type definitions from that file. If the source analyzer option -dotnetfuncs is used, the declarations for the member functions are also included in the .inc file. The .inc file is placed in the project specific directory ../project.4D/inc. The .inc file is then analyzed as source code, so that the class, type and optionally function declarations are loaded.

If the source analyzer under Windows is unable to locate the type library file, it issues the warning message:

could not open libraryname.tlb
In cross-platform development where you're analyzing your MSVC code in a Linux/Unix environment, the original .tlb, .olb, .exe or .dll type library can not be processed and no .inc file is generated. So when no matching .inc file is found, the source analyzer simply issues the warning message:
#import could not locate libraryname.tlh containing C++ definitions for type library
As a workaround for such situations, you can first analyze the code under Windows to generate the associated .inc files. After copying the source analyzer generated .inc files from the ../project.4D/inc directory to the ../imagix/user/cc_cfg/msvc_lib directory in your Linux/Unix environment, you can continue with Imagix 4D.

Note that Imagix 4D will load in your source code even if a warning is generated. If no messages are reported beyond the missing #import file warning, you can ignore the warning and consider your source code successfully analyzed. Furthermore, if you'd like to eliminate the warning about the missing file, you can create an empty text file with the correct name, and place it in one of the include directories with the regular header files.

.NET CLR (Managed Code) Files and #using

Under the Common Language Runtime (CLR) component of the .NET framework, Microsoft Visual C++ provides an alternative approach for supporting the use of symbols defined in other executables. The #using preprocessor directive supports referencing symbols defined in CLR .dll, .exe, .netmodule and .obj files, for example:

#using <System.Windows.Forms.dll>
Configuring for CLR
The compiler configuration file for Microsoft Visual C++, msvc_win.inc, contains special directives to support the Common Language Runtime. To reach these directives, the Imagix 4D project's data sources need to be defined with an option of either -D_MANAGED or -clr. Normally, the -clr option is defined automatically when you create an MSVC Project or MSVC Workspace / Solution data source to load a CLR-based Visual Studio project.

The option needs to be placed in the appropriate field of Project > Data Sources dialog. For Microsoft Visual Studio data sources, this is the Options field on the Project or Solution tab. For Dialog Based (C/C++) data sources, this is the PP Flags field on Source Files tab.

Analyzing a .inc file
When encountering a #using directive, the analyzer immediately looks for an equivalent .inc file. This is an Imagix 4D specific configuration file that contains definitions for the classes and types in the CLR file. For System.Windows.Forms.dll, the source analyzer will search for a .inc file named System.Windows.Forms.dll.inc.

The source analyzer checks for these .inc files in the include path specified through the -I and -S options. Additionally under Linux/Unix, the installation path ../imagix/user/cc_cfg/msvc_lib is checked. If the corresponding .inc file is found, it is analyzed as source code, just like a compiler configuration file.

Generating a .inc file
If no .inc file is found, what the source analyzer does next depends on the operating system. Under Windows, if Imagix 4D's source analyzer is unable to find an equivalent .inc file, it attempts to analyze the original .dll, .exe, .netmodule or .obj CLR file. The source analyzer checks the directories specified by the FRAMEWORKDIR and FRAMEWORKVERSION environmental variables, as well as the directories specified through the -I and -S flags.

If the source analyzer finds the binary CLR file, it processes that file and automatically generates a .inc file that contains the class and type definitions from that file. If the source analyzer option -dotnetfuncs is used, the declarations for the member functions are also included in the .inc file. The .inc file is placed in the project specific directory ../project.4D/inc. The .inc file is then analyzed as source code, so that the class, type and optionally function declarations are loaded.

If the source analyzer under Windows is unable to locate the CLR file, it issues the warning message:

could not find mscorlib.dll
In cross-platform development where you're analyzing your MSVC code in a Linux/Unix environment, the original .dll, .exe, .netmodule or .obj CLR file can not be processed and no .inc file is generated. So when no matching .inc file is found, the source analyzer simply issues the warning message:
#using could not locate mscorlib.dll.inc containing C++ definitions for assembly
As a workaround for such situations, you can first analyze the code under Windows to generate the associated .inc files. After copying the source analyzer generated .inc files from the ../project.4D/inc directory to the ../imagix/user/cc_cfg/msvc_lib directory in your Linux/Unix environment, you can continue with Imagix 4D.

The MSVC executable most commonly referenced in this way is mscorlib.dll. The Imagix 4D environment contains an equivalent header file, mscorlib.dll.inc. This is located in the installation directory ../imagix/user/cc_cfg/msvc_lib, which under Linux/Unix is automatically specified with an implicit -S option. Therefore, the specific directive #using <mscorlib.dll> is already supported. Under Windows, if mscorlib.dll can not be found, the easiest way to add this support is by copying mscorlib.dll.inc to ../imagix/user/cc_cfg.

Note that Imagix 4D will load in your source code even if a warning is generated. If no messages are reported beyond the missing #using file warning, you can ignore the warning and consider your source code successfully analyzed. Furthermore, if you'd like to eliminate the warning about the missing file, you can create an empty text file with the correct name, and place it in one of the include directories with the regular header files.

Multiple DLLs and Class Export / Import

The standard behavior of compilers is to apply a global naming rule whereby all top-level classes with the same name within the same compilation unit (executable, DLL or library) are considered to be the same class. Microsoft Visual C++ follows this rule. And this behavior is supported by the default behavior of Imagix 4D's source analyzer as long as you create an Imagix 4D project for each executable or DLL.

There may be times when you want to define a project that spans multiple compilation units. In such cases, the separate compilation units may happen to reuse the same top-level class names for what are actually different classes. This name conflict can be avoided through the source analyzer's option -uaggr (unique aggregate). When the -uaggr option is used, all top-level classes defined in different files are considered to be different classes, even if they have the same names.

This handles most issues of top-level class name collision. However, Microsoft Visual C++ allows top-level classes to be shared across compilation unit boundaries. Through the dllexport and dllimport extensions, MSVC enables specific classes to be defined as spanning DLLs. Such classes are defined by one DLL and declared in other DLLs where they are used. Meanwhile, regular classes continue to span just a single DLL.

Imagix 4D is able to handle such situations. The -uaggr option must be used in order to eliminate name conflicts between the regular classes. In order for the classes specified through the dllexport and dllimport extensions to be considered single classes spanning the DLLs, it is recommended that Imagix 4D's comboproject feature be used. In this approach, separate Imagix 4D projects are created for each DLL. Then, the individual projects are combined into a comboproject.

One additional benefit of this approach is that you end up with focused individual projects for when you want to study just a single DLL. And when you want to examine your full system, across multiple executables and DLLs, you're able to do that in the comboproject. For more information about comboprojects, see the section ComboProjects under the Projects and Data Collection section of this User Guide.