MATLAB: LoadLibrary, enums, and character literals

cdllenumloadlibraryMATLABr2013a

I've run into a rather daft problem with trying to load a DLL that I made. Basically all has been going well until recently when I added an enumerated type to the library. The type is declared as:
typedef enum {
COMMAND_GROUP_NULL = 0 ,
COMMAND_GROUP_RX = 'R',
COMMAND_GROUP_TX = 'T',
COMMAND_GROUP_GLOBAL = 'G',
COMMAND_GROUP_DEBUG = 'D',
COMMAND_GROUP_EMER = 'E'
} COMMAND_GROUPS;
In C this works perfectly well. However MATLAB fails when trying to load the library. I used the 'mfilename' name-value pair to try and debug what the issue what, and it appears that the above enumeration becomes:
enuminfo.COMMAND_GROUPS=struct('COMMAND_GROUP_NULL',0,'COMMAND_GROUP_RX',R,'COMMAND_GROUP_TX',T,'COMMAND_GROUP_GLOBAL',G,'COMMAND_GROUP_DEBUG',D,'COMMAND_GROUP_EMER',E);
Immediately the problem becomes obvious, MATLAB in its infinite wisdom decided that the C character literal should be converted into a letter not its ASCII value leading to the following error when loading the library:
Undefined function or variable 'R'
So, how do I fix this? Is there a way to get MATLAB to detect that the character literals should be converted into their ASCII equivalent? Or do I have to change the C and replace the literals with their value?
If the latter, this is clearly a bug which needs be fixed in MATLAB/Mex.
——
Also, I've just noticed that Mex screws up another of the enumerated types. In the second, a #define macro is used to perform a simple math function (bit shift and add) on four values to produce the value for the enum, e.g.:
#define COMMAND_BUILDER(g,a,b,t) ((((g)&255)<<0)+(((a)&255)<<8)+(((b)&255)<<16)+(((t)&255)<<24))
typedef enum {
COMMAND_1 = COMMAND_BUILDER('A','B','C','D'),
...
} COMMANDS;
This produces a structure in MATLAB in which all of the values are 0 – so basically it fails to do the calculation meaning the values don't get properly calculated. Not using the #define in this case would make the code completely unreadable as the command strings would make no sense being written as the result of the calculation.
EDIT: Ignore the above about #defines, they are calculated correctly if I remove the character literals and put the integer values as arguments. e.g.
COMMAND_BUILDER(0x41,0x42,0x43,0x44)
But again, this is far less readable than using 'A','B','C','D', etc.
——
  • MATLAB Version: R2013a (32bit)
  • Mex Compiler: Windows SDK 7.1 (32bit)
  • OS: Windows 8.1 x64

Best Answer

This is a bug/limitation in the perl script that parses the header file. Because the perl script works from a pre-procesed header file (.i) it never sees #define statements therefor they have no impact on the result.
This can be patched by editing the file toolbox\matlab\general\private\prototypes.pl and adding the line
$_=ord($_) if /^[^0-9]$/;
After the line
$_=eval($inp);
Of sub ParseConstExp this should be line 774 in R2013b.
The usual caveats apply when patching your copy of MATLAB. Back up the original and this is not an officially supported solution. I can't guarantee something else did not break...
I have filed a bug report for this.