LoadLibrary, enums, and character literals

4 visualizaciones (últimos 30 días)
Thomas Carpenter
Thomas Carpenter el 11 de Mayo de 2015
Editada: Thomas Carpenter el 16 de Mayo de 2015
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
  3 comentarios
Walter Roberson
Walter Roberson el 11 de Mayo de 2015
Try
#define A int('A')
as an experiment
Thomas Carpenter
Thomas Carpenter el 11 de Mayo de 2015
@Walter I tried that, but curiously MATLAB removes any entry which contains that #define as in or as its value - there are no errors, just the field in the enum disappears.

Iniciar sesión para comentar.

Respuesta aceptada

Philip Borghesani
Philip Borghesani el 11 de Mayo de 2015
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.
  1 comentario
Thomas Carpenter
Thomas Carpenter el 16 de Mayo de 2015
Editada: Thomas Carpenter el 16 de Mayo de 2015
Thanks for the response and explaining why it fails. Unfortunately as the DLL is being used as part of a research platform, and is being used on networked computers at a university, I can't make any patches to the MATLAB software, so I will have to stick with the #defines for characters approach:
#define A 0x41
...

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre C Shared Library Integration en Help Center y File Exchange.

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by