Export (0) Print
Expand All

How to: Marshal Between X++ and CLR Primitive Types

Dynamics AX 2009

In Microsoft Dynamics AX, the X++ language does implicit conversion or marshaling between several X++ primitive types and their counterpart types managed by the common language runtime (CLR). This means that the X++ assignment operator, the single equal sign (=), can be used between certain pairings of an X++ type with a CLR type.

Implicit marshaling with the X++ assignment operator works in both directions, either from X++ types to CLR types, or from CLR to X++.

A .NET managed assembly might provide a useful method that returns a System.String object. You can call the method and capture the returned System.String in a variable of that type that you declare in your X++ code.

But if your next step is to pass that string into an X++ method that takes a str, you must first marshal the System.String into a str.

For more information, see How to: Substitute Primitive Parameter Types Between the CLR and X++.

Each row in the following table lists a pairing of types that are implicitly marshaled by the X++ assignment operator.

NoteNote

There is no implicit marshaling between the X++ utcdatetime and .NET Framework System.DateTime type. For more information about how to convert between utcdatetime and System.DateTime, see How to: Convert Between utcdatetime and System.DateTime.


The following code sample shows the marshaling between the .NET Framework System.Boolean type and its X++ counterpart boolean.

static void JobBooleanMarshal(Args _args) // X++ job.
{
    System.Boolean netBool; // .NET
    boolean xppBool; // X++
    ;
    // Marshal .NET to X++.
    xppBool = false;

    netBool = true;
    xppBool = netBool; // Marshals.
    if (true == xppBool)
    {
        info("A1. Good, .NET was marshaled to X++.");
    }
    else
    {
        info("A2. Bad, .NET was not marshaled to X++.");
    }
    // Marshal X++ to .NET.
    netBool = true;
    
    xppBool = false;
    netBool = xppBool; // Marshals.
    
    xppBool = true;
    xppBool = netBool;
    if (false == xppBool)
    {
        info("B1. Good, X++ was marshaled to .NET.");
    }
    else
    {
        info("B2. Bad, X++ was not marshaled to .NET.");
    }
}
/***** Actual infolog output
Message (01:08:32 pm)
A1. Good, .NET was marshaled to X++.
B1. Good, X++ was marshaled to .NET.
*****/

The following code sample shows the marshaling between the .NET Framework System.DateTime type and the X++ date type. From System.DateTime, there is no marshaling to the X++ utcdatetime type. And there is no marshaling from System.DateTime to the timeOfDay extended data type (which is an int).

static void JobDateTimeMarshal(Args _args)
{
    System.DateTime netDttm;
    date xppDate;
    str strTemp;
    ;
    // Marshal .NET to X++.
    netDttm = new System.DateTime(1988,7,20 ,13,44,55);
    xppDate = netDttm; // Marshals.
    if (date2str(xppDate,321, 2,2,2,2,4) == "1988.07.20")
    {
        info("A1. Good, .NET was marshaled to X++.");
    }
    else
    {
        info("A2. Bad, .NET was not marshaled to X++.");
    }
    // Marshal X++ to .NET.
    xppDate = 25\11\2002;
    netDttm = xppDate; // Marshals.
    strTemp = netDttm.ToString("s");
    if (strTemp == "2002-11-25T00:00:00")
    {
        info("B1. Good, X++ was marshaled to .NET.");
    }
    else
    {
        info("B2. Bad, X++ was not marshaled to .NET.");
    }
}

The following code sample shows the marshaling between the .NET Framework System.Int32 type and its X++ counterpart int.

static void JobInt32Marshal(Args _args)
{
    System.Int32 netInt;
    int xppInt;
    ;
    // Marshal .NET to X++.
    netInt = 33;
    xppInt = netInt; // Marshals.
    if (33 == xppInt)
    {
        info("A1. Good, .NET was marshaled to X++.");
    }
    else
    {
        info("A2. Bad, .NET was not marshaled to X++.");
    }
    // Marshal X++ to .NET.
    netInt = 0;

    xppInt = 444;
    netInt = xppInt; // Marshals.

    xppInt = 0;
    xppInt = netInt;
    if (444 == xppInt)
    {
        info("B1. Good, X++ was marshaled to .NET.");
    }
    else
    {
        info("B2. Bad, X++ was not marshaled to .NET.");
    }
}

X++ int Does Not Marshal to System.Int64

Automatic marshaling works between the X++ int64 type and the .NET Framework type System.Int64, just as marshaling works between the X++ int and the .NET System.Int32.

An X++ int does not marshal to a System.Int64, nor the reverse. A System.Int32 does not marshal to an X++ int64, nor the reverse.

The following code sample shows the marshaling between the .NET Framework System.String type and its X++ counterpart str.

static void JobStringMarshal(Args _args)
{
    System.String netString;
    str xppString;
    ;
    // Marshal .NET to X++.
    netString = "cat";
    xppString = netString; // Marshals.
    if ("cat" == xppString)
    {
        info("A1. Good, .NET was marshaled to X++.");
    }
    else
    {
        info("A2. Bad, .NET was not marshaled to X++.");
    }
    // Marshal X++ to .NET.
    netString = "";

    xppString = "dog";
    netString = xppString; // Marshals.

    xppString = "";
    xppString = netString;
    if ("dog" == xppString)
    {
        info("B1. Good, X++ was marshaled to .NET.");
    }
    else
    {
        info("B2. Bad, X++ was not marshaled to .NET.");
    }

/***** Actual infolog output
Message (06:27:19 am)
A1. Good, .NET was marshaled to X++.
B1. Good, X++ was marshaled to .NET.
*****/
}

The following code sample shows the marshaling between the .NET Framework System.Guid type and its X++ counterpart guid.

static void JobGuidMarshal(Args _args)
{
    System.Guid netGuid;
    guid xppGuid;
    str sGuid1
        ,sGuid2;
    ;
    sGuid1 = "10001000-1000-1000-1000-100010001000";
    sGuid2 = "20002000-2000-2000-2000-200020002000";
    // Marshal .NET to X++.
    netGuid = Global::guidFromString(sGuid1);
    xppGuid = netGuid; // Marshals.
    if (xppGuid == Global::guidFromString(sGuid1))
    {
        info("A1. Good, .NET was marshaled to X++.");
    }
    else
    {
        info("A2. Bad, .NET was not marshaled to X++.");
    }
    // Marshal X++ to .NET.
    xppGuid = Global::guidFromString(sGuid2);
    netGuid = xppGuid; // Marshals.
    xppGuid = Global::guidFromString(sGuid1);
    xppGuid = netGuid;
    if (xppGuid == Global::guidFromString(sGuid2))
    {
        info("B1. Good, X++ was marshaled to .NET.");
    }
    else
    {
        info("B2. Bad, X++ was not marshaled to .NET.");
    }
}

The following code sample shows the marshaling between the .NET Framework types System.Single and System.Double, and their mutual X++ counterpart real. The sample shows that the X++ real does marshal in both directions, with both .NET Framework types.

static void JobRealMarshal(Args _args)
{
    str xppStr;
    real xppReal;
    System.Double netDouble;
    System.Single netSingle;
    ;
    xppReal = 1.2305e+6;

    netSingle = xppReal;
    xppReal = 0.0;
    xppReal = netSingle;

    netDouble = xppReal;
    xppReal = 0.0;
    xppReal = netDouble;

    netSingle = xppReal;
    xppStr = System.Convert::ToString(netSingle);
    info(xppStr);
}
/***** Actual infolog output
Message (01:39:56 pm)
1230500
*****/

When you work with .NET primitive types in X++ code, you can use the X++ equal sign (=) assignment operator. However, no other operators can be used with CLR primitives. For instance, you cannot use the comparison operators (such as == or >). Also, you cannot use bitwise operators (such as & or |).

For more information about X++ operators with .NET primitive types, see Operators for CLR Primitive Types.

Community Additions

ADD
Show:
© 2014 Microsoft