Breaking changes for C++ API?
Show older comments
Updated: I made a minimal example of the issue. Older versions of MATLAB (I was using 2015b) work fine with this code. MATLAB 2019b throws a NoActiveContextTypeError exception. It is possible to continue past the exception, but I'm not sure that this is safe.

I've attached a visual studio solution that points to my matlab installation libraries. You might need to change the path in project settings -- I have it pointing at D:\MATLAB\R2019b in three places:
- VC++ Directories / Include Directories (D:\MATLAB\R2019b\extern\include)
- C/C++ General / Additional Include Directories (D:\MATLAB\R2019b\extern\include)
- Linker / General / Additional Library Directories (D:\MATLAB\R2019b\extern\lib\win64\microsoft)
- Also call "matlab /regserver" in MATLAB\R2019b\bin\win64 if you need to
As discussed below, adding an initial field name instead of NULL doesn't change the behavior.
What is the reason for the exception and is this code safe?
-------------- Original Question --------------
I have C++ code that starts a matlab session using engOpenSingleUse(). It builds data structures using mxCreateStructMatrix() and sends them over to Matlab using engPutVariable(). It executes some user code via engEvalString(), and fetches the results with engGetVariable(). This has all been working fine for a few years. Recently I was unable to get my code to work with MATLAB 2019b. It works fine with 2015b. When linking with 2019b stuff I get the following cryptic error on mxCreateStructMatrix():

engOpenSingleUse() seems to work. Was mxCreateStructMatrix depricated or were breaking changes made to the interface? I am confused about the difference between the C Matrix API and the newer C++ API that was released around 2017b.
I am looking for a solution we can deploy for calling MATLAB code and sending data from a C++ application that is compatible with a wide range of MATLAB versions.
2 Comments
James Tursa
on 25 Sep 2019
Edited: James Tursa
on 25 Sep 2019
What is the SetField( ) function? Something you wrote? How does this function work when the struct in question does not have the given field? Can you show the code for this?
James Tursa
on 25 Sep 2019
The new C++ API interface is completely different from the C API that you are currently using. You would have to overhaul your code to use the C++ API, which may not be worth it to you, particularly if you want to support older versions of MATLAB.
Answers (2)
James Tursa
on 25 Sep 2019
Edited: James Tursa
on 25 Sep 2019
0 votes
The current online doc for mxCreateStructMatrix( ) says the last argument must contain "... one or more field names ...", which your code does not do. If I look at the doc from an older version of MATLAB (R2014a) it simply says "List of field names". So maybe something has changed, and it won't take a NULL for this anymore.
Do you know all the field names ("generators", "primary_loads", etc.) in advance? Can you create the struct up front with all of those field names instead of trying to add them in piecemeal later on?
Or, create the struct with one field name (e.g., "dummy" or "unused") that you don't use, and leave all your current code the same. You could even remove this field later if you didn't want it hanging around and cluttering up your field names. Removing a field like this should be a very fast operation, since only a few mxArray pointers get moved in memory ... no mxArray data actually gets moved.
9 Comments
Jonathan Awerbuch
on 26 Sep 2019
James Tursa
on 26 Sep 2019
Edited: James Tursa
on 26 Sep 2019
I don't know any details about NoActiveContextTypeError ... I was just guessing that it had something to do with a NULL pointer where it was expecting content.
For your fns, I think you are missing one level of indirection. That last argument needs to be a (char **) type. (I.e., from an array of char *). Maybe try this instead:
sp_ = mxCreateStructMatrix(1, 1, 1, &fns);
But even with that I still think you've got the wrong type for fns to hold the pointer. Maybe just do it like this:
const char *fns[1] = {"test"};
sp_ = mxCreateStructMatrix(1, 1, 1, fns);
Jonathan Awerbuch
on 26 Sep 2019
James Tursa
on 26 Sep 2019
Edited: James Tursa
on 26 Sep 2019
??? ... what the heck is going on? I need to think about this some more ...
Can you show me the SetField( ) code?
Did you also write ConvertToMxArray( )?
Jonathan Awerbuch
on 26 Sep 2019
Jonathan Awerbuch
on 26 Sep 2019
James Tursa
on 26 Sep 2019
Edited: James Tursa
on 26 Sep 2019
I haven't looked at your zip file or tried to set anything up, but I did notice the following with your latest image post.
Your use of the ret variable is incorrect and also the source of a crash. You are supposed to pass in the address of an int so that engOpenSIngleUse( ) can return a value in it. I.e., you are supposed to pass a pointer to valid memory. But what you have done is to essentially pass a NULL pointer into the function (the ret value is 0) which when deferenced inside the function will result in an invalid memory access and I would expect a crash.
Fix all this up first to make sure it isn't contributing to your problems.
int ret; // make ret an int, not a pointer to int
Engine *ep = engOpenSingleUse( "", NULL, &ret ); // pass the address of ret
You should probably check that the values of ep and sp are not NULL before using them, btw.
Jonathan Awerbuch
on 26 Sep 2019
James Tursa
on 26 Sep 2019
Edited: James Tursa
on 26 Sep 2019
"The autos appear to be resolving to Engine* and mxArray* respectively, not ints, so I'm not sure I understand what you're saying there"
That was a C response by me, which I removed from my post once I remembered this was C++ code, but you looked at my response before I removed that section. :)
(And I don't think I have given you much support yet ...)
Paul Williams
on 27 Sep 2019
0 votes
If you have more than one MATLAB installed on your system it could be loading the run-time libraries from an earlier version.
Categories
Find more on C Shared Library Integration in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


