Monday, March 14, 2011

How to solve 'Error: Wrong argument type for function' error message when working with CLR

When working with the common language runtime (CLR) and its primitive data types you may run into following error code:

   Error executing code.  Wrong argument type for function.

When you just rewrite your code a bit, all of sudden it works.  Only, do you know what made it work?  Did you find an explanation for the error message?

I try to give some insight on the error cause.  But to give some sort of explanation, we need to look at some theory first.  About X++ and its support for marshalling.
First, let’s look at the CLR primitive types and their matching types within X++.



When working with these types in X++, you’ll see that the X++ does an implicit conversion (also called marshalling) between the two types. This makes it quite easy to mix them in your code. All that is needed is the single equal sign as your assignment operator (=).

Take a look at following example:

static void Marshalling01(Args _args)
{
    System.String   myCLRString;
    Str             myXppString;
    ;

    myCLRString="Hello";
    myXPPString=myCLRString;

    info(myXppString);
}

This will work both ways, so going back and forth between X++ and CLR.

But there is a little catch, when such code doesn’t work.

When you supply the CLR type as a parameter of a X++ method, this might fail. So you must make sure your conversion has been taken place before that.

Rules that apply:
  • An X++ type can be used as a parameter in a call to a .NET Framework method.
  • An X++ type can also be used as a parameter in a call to a X++ method, expecting a CLR primitive.
  • But a CLR primitive cannot be used in a X++ method expecting an X++ type.
So this substitution works one way only.

Example, what will not work:
(but does compile)

static void DemoA(Args _args)
{
    ;
    info(strfmt('The current folder is %1',System.IO.Directory::GetCurrentDirectory()));
}


Instead, what will work.

static void DemoB(Args _args)
{
    str   myfolder=System.IO.Directory::GetCurrentDirectory();
    ;
    info(strfmt('The current folder is %1',myfolder));
}

So make sure you declare a local variable, which you use to do the implicit conversion between X++ and CLR.  And you are good to go.

An extra note on the side:
The only operator to use when working with CLR primitive types is the equal sign =, so by making an assignment. You cannot use other operators, like for example for comparison. So no == or > (bigger than) or < (smaller than).

1 comment:

  1. You can complie the object mentioned in stack trace to resovle this error.

    ReplyDelete