COM Interoperability
The following
code example demonstrates COM interoperability with the XML document
type in the Microsoft XML Core Services (MSXML) 6.0 COM component. The
example assumes that you’ve installed MSXML. The MSXML document is first
instantiated and wrapped in a Dynamics AX COM object wrapper. A COM
variant wrapper is created for a COM string. The direction of the
variant is into the COM component. The root element and head element
variables are declared as COM objects. The example shows how to fill a
string variant with an X++ string and then use the variant as an
argument to a COM method, loadXml.
The statement that creates the head element demonstrates how the
Dynamics AX runtime automatically converts Dynamics AX primitive objects
into COM variants.
static void Job2(Args _args) { COM doc = new COM("Msxml2.DomDocument.6.0"); COMVariant rootXml = new COMVariant(COMVariantInOut::In,COMVariantType::VT_BSTR); COM rootElement; COM headElement; ; rootXml.bStr("<Root></Root>"); doc.loadXml(rootXml); rootElement = doc.documentElement(); headElement = doc.createElement("Head"); rootElement.appendChild(headElement); print doc.xml(); pause; }
|
Macros
The
macro capabilities in X++ enable you to define and use constants and
perform conditional compilation. Macros are unstructured because they
are not defined in the X++ syntax. Macros are handled before the source
code is compiled. You can add macros anywhere you write source code: in
methods and in class declarations.
Table 11 shows the supported macro directives.
Table 11. Macro Directives
Directive | Description |
---|
#define
#globaldefine | Defines a macro with a value.
#define.MyMacro(SomeValue)
Defines the macro MyMacro with the value SomeValue. |
#macro
...
#endmacro
#localmacro
...
#endmacro | Defines a macro with a value spanning multiple lines.
#macro.MyMacro print "foo"; print "bar"; #endmacro
Defines the macro MyMacro with a multiple-line value. |
#macrolib | Includes a macro library. As a shorthand form of this directive, you can omit macrolib.
#macrolib.MyMacroLibrary #MyMacroLibrary
Both include the macro library MyMacroLibrary, which is defined under the Macros node in the AOT. |
#MyMacro | Replaces a macro with its value.
#define.MyMacro("Hello World") print #MyMacro;
Defines the macro MyMacro and prints its value. In this example, “Hello World” would be printed. |
#definc
#defdec | Increments and decrements the value of a macro; typically used when the value is an integer.
Decrements the value of the macro MyIntMacro. |
#undef | Removes the definition of a macro.
Removes the definition of the macro MyMacro. |
#if
...
#endif | Conditional compile. If the macro referenced by the #if directive is defined or has a specific value, the following text is included in the compilation.
#if.MyMacro print "MyMacro is defined"; #endif
If MyMacro is defined, the print statement is included as part of the source code.
#if.MyMacro(SomeValue) print "MyMacro is defined and has value: SomeValue"; #endif
If MyMacro has SomeValue, the print statement is included as part of the source code. |
#ifnot
...
#endif | Conditional compile. If the macro referenced by the #ifnot directive isn’t defined or doesn’t have a specific value, the following text is included in the compilation.
#ifnot.MyMacro print "MyMacro is not defined"; #endif
If MyMacro is not defined, the print statement is included as part of the source code.
#ifnot.MyMacro(SomeValue) print "MyMacro does not have value: SomeValue; or it is not defined"; #endif
If MyMacro is not defined, or does not have SomeValue, the print statement is included as part of the source code. |
The following example shows a macro definition and reference.
void myMethod() { #define.HelloWorld("Hello World") ; print #HelloWorld; pause; }
|
As we noted in Table 11,
a macro library is created under the Macros node in the AOT. The
library is included in a class declaration header or class method, as
shown in the following example.
class myClass { #MyMacroLibrary1 } public void myMethod() { #MyMacroLibrary2 ; #MacroFromMyMacroLibrary1 #MacroFromMyMacroLibrary2 }
|
A macro can also
use parameters. The compiler inserts the parameters at the positions of
the placeholders. The following example shows a local macro using
parameters.
void myMethod() { #localmacro.add %1 + %2 #endmacro
print #add(1, 2); print #add("Hello", "World"); pause; }
|
When a macro library is
included or a macro is defined in the class declaration of a class, the
macro can be used in the class and in all classes derived from the
class. A subclass can redefine the macro.
Comments
X++ allows single-line and multiple-line comments. Single-line comments start with // and end at the end of the line. Multiple-line comments start with /* and ended with */. You can’t nest multiple-line comments.
You can add reminders
to yourself in comments that the compiler picks up and presents to you
as tasks in its output window. To set up these tasks, start a
single-line comment with the word TODO
(all uppercase). Be aware that tasks occurring inside multiple-line
comments are treated as commented out, so the compiler doesn’t pick them
up.
Here is a code example with comments reminding the developer to add a new procedure while commenting out an existing procedure.
public void myMethod() { //Declare variables int value;
//TODO Validate if calculation is really required /* //Perform calculation value = this.calc(); */ ... }
|
XML Documentation
You can document XML
methods and classes directly in X++ by writing /// (triple slash)
followed by structured documentation in XML format. The XML
documentation must be above the actual code.
The contents of XML are
strict and must align with the code. The Best Practices tool contains a
set of rules that can validate the XML documentation. The supported
tags are shown in Table 12.
Table 12. XML Tags Supported for XML Documentation
Tag | Description |
---|
<summary> | Describes a method or a class. |
<param> | Describes the parameters of a method. |
<returns> | Describes the return value of a method. |
<remarks> | Adds information that supplements the information provided in the <summary> tag. |
<exception> | Documents exceptions that are thrown by a method. |
<permission> | Describes the permission needed to access methods using CodeAccessSecurity.demand. |
<seealso> | Lists references to related and relevant documentation. |
You
can extract the written XML documentation for an AOT project by using
the Add-Ins menu option Extract XML Documentation. One XML file
containing all the documentation written for the elements inside the
project is produced. You can also use this XML file to publish the
documentation.
Here is a code example in which XML documentation has been written for a static method on the Global class.
/// <summary> /// Converts an X++ utcdatetime value to a .NET System.DateTime object. /// </summary> /// <param name="_utcDateTime"> /// The X++ utcdatetime to convert. /// </param> /// <returns> /// A .NET System.DateTime object. /// </returns> static client server anytype utcDateTime2SystemDateTime(utcdatetime _utcDateTime) { ; return CLRInterop::getObjectForAnyType(_utcDateTime); }
|