The OpenFlight API can only be initialized and terminated one time per process. That means that you cannot make the following calls in the same process:
Check the documentation on mgInit and mgExit for more information.
Users have worked around this limitation using, for example, the techniques listed here:
1) Initialize the OpenFlight API only the first time an OpenFlight file is to be read and exit the API when your app terminates.
2) Initialize the OpenFlight API when your app starts and exit the API when your app terminates. This is similar to #1 but more symmetric.
3) Move the OpenFlight file processing (init, open, exit) into it's own process that you fire up each time you want to read an OpenFlight file.
Let us know if you have further questions.
Thanks for your kindly reply!
if it is possible that i can load the api dynmaically?so when i end the api ,i can free the labrory freely?
If you are considering a LoadLibrary/FreeLibrary approach, I don't think that would work well. It may solve the immediate problem but introduce others. For example, you would not be able to call OpenFlight API functions directly anymore, you'd have to call through function pointers (using GetProcAddress - yuck). If you call only 4 API functions (mgInit, mgOpenDb, mgCloseDb and mgExit) this might be manageable but I suspect you will be calling many more functions. Using GetProcAddress for each could be a bit more work than you want to do.
Also if you do try this, be aware that the "OpenFlight API" (in memory) is comprised of more than just one DLL (mgapilib.dll). Put another way, mgapilib.dll (the main OpenFlight API DLL) depends on several other DLLs. When you "LoadLibrary" on mgapilib.dll those other (dependent) DLLs are loaded for free but when you "FreeLibrary" you have to unload each of them explicitly. i.e., Calling FreeLibrary on mgapilib.dll does not automatically free the other dependent DLLs that LoadLibrary loaded.
The more I think about it, I don't believe LoadLibrary/FreeLibrary is the best option.
Before deciding on an approach, you might consider the following.
If you are ok with the OpenFlight API being loaded for the duration of your MatLab session, it is certainly the easiest option to simply call mgInit before the first OpenFlight access and mgExit when MatLab terminates. Or even more simply (symmetric) to call mgInit at MatLab startup and mgExit at MatLab termination.
If you really don't want the OpenFlight API to "stick around" during the MatLab session and only want it "in memory" when you are loading an OpenFlight file, your choice would be to create a process for OpenFlight file loading. The process would mgInit, mgOpenDb, mgCloseDb, mgExit and then go away (after having transferred the OpenFlight file contents to in-memory MatLab).
Those are the two basic models you can follow.
Let us know if you have further questions.
Ok,thanks for your advise.I try the method of load API dynamically,but it also couldn't work. My code like this:
MGDLL = LoadLibrary("mgapilib.dll");
if (NULL==MGDLL )
printf("load mgapilib.dll failed!")
MGInit = ( MgInit )GetProcAddress(MGDLL, "mgInit");
MGCloseDb = ( MgCloseDb )GetProcAddress(MGDLL, "mgCloseDb");
MGWalk = ( MgWalk )GetProcAddress(MGDLL, "mgWalk");
MGMostDetail = ( MgMostDetail )GetProcAddress(MGDLL, "mgMostDetail");
MGExit = ( MgExit )GetProcAddress(MGDLL, "mgExit");
MGOpenDb = ( MgOpenDb )GetProcAddress(MGDLL, "mgOpenDb");
MGFree = ( MgFree )GetProcAddress(MGDLL, "mgFree");
if(!MGInit || !MGCloseDb || !MGWalk ||
|| !MGMostDetail || ! MGExit || !MGOpenDb || !MGFree)
then i called , MGInit, MGOpenDb,MGCloseDb,MGExit and then free the labrary.
MGInit = NULL;
MGCloseDb = NULL;
MGWalk = NULL;
MGMostDetail = NULL;
MGExit = NULL;
MGOpenDb = NULL;
MGFree = NULL;
then i loadlary the API DLL again and call the function,MGInit, MGOpenDb,MGCloseDb,MGExit again,but the MGOpenDb failed when i second called.so the other function couldn't work well without the data db.
I don't konw why the MGOpenDb couldn't work?just because i called the MGInit secodly?
As your know, The matlab S-function called the it's callback function like mdlInitializeSizes(SimStruct *S),mdlStart(SimStruct *S) from time to time , so the mginit may be called one or more times, so the second time running the simulik block ,it couldn't work!
why the FreeLibrary(MGDLL) couldn't free rhe MGInit and other function?
As I noted in my earlier message, it would not be enough to FreeLibrary on just the mgapilib.dll. You would have to FreeLibrary on all the dependent libraries as well. Again, that is because when you call LoadLibrary on mgapilib.dll, several other "dependent" libraries will be loaded automatically for you but when you FreeLibrary later on, those dependent libraries are not automatically removed.
Once you manage to unload ALL the proper (dependent) DLLs, in theory this should work. I am certainly no expert on the Windows functions LoadLibrary so I don't know of any reason this would not work. Perhaps there would be something else prohibiting this from working. Sorry if I cannot offer more assistance.
If you do discover some "tricks" to making this work, let us know.
yes ,thank for your help!
i find that ,i can call the API like this without mgEXIt.
I can call the mgInit and mgXXXFUN many times in one procee.when the program qute,the API many qute also. so the mgEXIT many not to need i the program!
This method may cause some risk,i dont konw! hahaha!
this method like the calling order,just withou the mgExit and many times mgInit!
I use the fltapi to read the flt datas from the FLT file.I intergrate the API on the Matlab environment,but I find that ,I just can run Matlab once a time before close the matlab.Later ,i intergrate the API on the VC environment ,I try the call the api like this:
but when i call mgOpenDb secondly, the open flt failure?
Is it that the FLTAPI couldn't complete exit when i call mgExit ? so the matlab enviroment just can run once a time?