LoadLibrary, enums, and character literals

조회 수: 4 (최근 30일)
Thomas Carpenter
Thomas Carpenter 2015년 5월 11일
편집: Thomas Carpenter 2015년 5월 16일
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
Walter Roberson
Walter Roberson 2015년 5월 11일
Try
#define A int('A')
as an experiment
Thomas Carpenter
Thomas Carpenter 2015년 5월 11일
@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.

댓글을 달려면 로그인하십시오.

채택된 답변

Philip Borghesani
Philip Borghesani 2015년 5월 11일
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
Thomas Carpenter
Thomas Carpenter 2015년 5월 16일
편집: Thomas Carpenter 2015년 5월 16일
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
...

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 C Shared Library Integration에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by