MATLAB Answers

Breaking changes for C++ API?

15 ビュー (過去 30 日間)
Jonathan Awerbuch
Jonathan Awerbuch 2019 年 9 月 25 日
Edited: Jonathan Awerbuch 2019 年 10 月 1 日
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 件のコメント

James Tursa
James Tursa 2019 年 9 月 25 日
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
James Tursa 2019 年 9 月 25 日
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.

サインイン to comment.

件の回答 (2)

James Tursa
James Tursa 2019 年 9 月 25 日
編集済み: James Tursa 2019 年 9 月 25 日
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 件のコメント

表示 6 件の古いコメント
James Tursa
James Tursa 2019 年 9 月 26 日
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
Jonathan Awerbuch 2019 年 9 月 26 日
Okay, made those changes. 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, but they are declared explicitly as class members in production anyway. The int pointer set to null was just sloppiness from trying to go too fast-- sorry about that. In the production code I check for error conditions, but leaving all that out here for simplicity. Same exception now. Attached is the code with those changes. Thanks for the support!
James Tursa
James Tursa 2019 年 9 月 26 日
"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 ...)

サインイン to comment.

Paul Williams
Paul Williams 2019 年 9 月 27 日
If you have more than one MATLAB installed on your system it could be loading the run-time libraries from an earlier version.

  0 件のコメント

サインイン to comment.

サインイン してこの質問に回答します。





Translated by