How To Call Dll Functions In Matlab !!TOP!!
Download File >>> https://urloso.com/2t7eH7
One difference between the code for DLL2 and the code for DLL1 is that GetCpuSpeed() is declared using __stdcall. This is required for any C/C++ function that you want to use with VB. Here is what MSDN says about the __stdcall calling convention:
The Microsoft C++ compilers encode the names of symbols in C++ programs to include type information in the name. This is called "name decoration", or "name mangling". The purpose of this is to ensure type-safe linking. The C++ language allows function overloading where functions with the same name are only distinguished from one another by the data types of the arguments to the functions. Name decoration enables the linker to distinguish between different versions of overloaded functions because the names of the functions are encoded or decorated differently.
I have a MATLAB C DLL compiled using MATLAB 2017A (fully 64 bit), and the respective version of the Compiler SDK. I used Visual Studio 2017 Community (again, fully 64 bit...bitness is not the issue) to create a wrapper and console application to independently verify the DLL. The console application works fine, both as a single DLL function, and by calling separate init, function, term functions.
When I import the DLL into Labview 2016 64bit, the import goes fine and the first run of the DLL file works just fine. However, Labview reports an exception from the DLL when the VI is run a second time or more. In my investigation, it looks like the MATLAB terminate functions fail the first time, and consequently the initialization of the next VI run fails, and crashes Labview.
And how did you test that? A simple C application usually links to the DLL statically through an import library. This means the DLL is loaded at program start, then stays in memory as long as the application is active, and when the application terminates, the DLL is also unloaded by Windows.
In LabVIEW this is usually quite different. Because I never used Matlab DLLs from within LabVIEW, I'm not exactly sure about the specifics of integrating such a DLL. But if you use the Call Library Node (CLN), the DLL gets loaded for every Call Library Node that calls into that DLL at the time the VI containing the CLN gets loaded. The first load will actually load the DLL, all subsequent loads will increment a reference counter for that DLL. When a VI containing a CLN is unloaded, LabVIEW will also unload the according DLL, which decrements the reference count and if that reaches zero, Windows will unload the complete DLL.
During final unloading of the DLL, the DLLMain() function is called by Windows with the selector DLL_PROCESS_DETACH. And here things get interesting. If this function does something bad (illegal memory access or something) it will cause an error or in some cases a complete crash of LabVIEW, when the DLL was referenced through the CLN.
In order to simulate how it works in LabVIEW, you would have to not use the import library in your linking stage, but instead do an explicit LoadLibrary() on program start. then some GetProcAddress() to get a function pointer and call those functions though that pointer, and at some point before you actually terminate your program, call FreeLibrary() for that handle as often as you called LoadLibrary() if you called this multiple times. Only when this doesn't show the problem you observe in LabVIEW, can you conclude that LabVIEW is doing something illegal. Explicitly loading and unloading a shared library is a legal operation, and if the DLL can't deal with that properly, it's the fault of the DLL, not the application trying to load and unload the DLL explicitly.
Thanks for the lengthy response, it gives me a few things to think about. I am pretty confident that the behavior of the DLL is not at play, though I respect your comments about the differences with respect to how the libraries are loaded and unloaded. I like the idea of trying to mimic the approach that LabVIEW uses to try to confirm the issue. In the previous discussion on crashing libraries, one person had mentioned (perhaps that you hinted at) that LabVIEW loads the DLL when the VI is loaded. However, if you call the VI that contains the DLL by reference, then LabVIEW will not load it until that call by reference occurs, and should unload it when that reference is closed. I haven't tried that, so I will add that to the list of things to try.
I do suspect that the exception is caused when the DLL calls the MATLAB libraryTerminate() function (I uncommented my DLL code calls line by line until the exception would take place). If I leave the MATLAB libraryTerminate() function commented out, LabVIEW can call the DLL without any issue the second and subsequent times.
As you said, mimicking the way the DLL is called in both directions will be key in understanding what the issue is. If you are interested, I could make the DLLs, C, and H files available or visible to see if I have made an obvious error in my coding, which is entirely possible.
How would I go about dynamically loading AND unloading (forced if needed) a VI calling a DLL? It appears there are issues with the underlying MATLAB runtime that dislikes re-initializing the application after termination. Since the C application works fine, I can safely assume that would you indicated is occurring, that the DLL is called at load time, and not unloaded until the application ends. The crash I managed to recreate was initializing and terminating the runtime more than once in a single application execution. The is likely the same reason that LabVIEW is crashing, as it loads the DLL the first time the VI is called/put into memory, but it never releases the DLL until LabVIEW is fully closed.
Why couldn't you export a separate initialize() and terminate() function from your wrapper DLL and let your application call those explicitly on startup and termination (and remember that after calling terminate() you need to restart LabVIEW?
If the Matlab runtime does require a complete unload and reload of it after a terminate call, that is a bug in the runtime DLL, but since you have a wrapper DLL you can do a lot of customization when you call the initialize and terminate functions.
A module-definition or DEF file (*.def) is a text file containing one or more module statements that describe various attributes of a DLL. If you are not using the __declspec(dllexport) keyword to export the DLL's functions, the DLL requires a DEF file.
The EXPORTS statement lists the names and, optionally, the ordinal values of the functions exported by the DLL. You assign the function an ordinal value by following the function's name with an at sign (@) and a number. When you specify ordinal values, they must be in the range 1 through N, where N is the number of functions exported by the DLL. If you want to export functions by ordinal, see Exporting Functions from a DLL by Ordinal Rather Than by Name as well as this topic.
If you use the MFC DLL Wizard to create an MFC DLL, the wizard creates a skeleton DEF file for you and automatically adds it to your project. Add the names of the functions to be exported to this file. For non-MFC DLLs, create the DEF file yourself and add it to your project. Then go to Project > Properties > Linker > Input > Module Definition File and enter the name of the DEF file. Repeat this step for each configuration and platform, or do it all at once by selecting Configuration = All Configurations, and Platform = All Platforms.
If you are exporting functions in a C++ file, you have to either place the decorated names in the DEF file or define your exported functions with standard C linkage by using extern "C". If you need to place the decorated names in the DEF file, you can obtain them by using the DUMPBIN tool or by using the linker /MAP option. Note that the decorated names produced by the compiler are compiler specific. If you place the decorated names produced by the Microsoft C++ compiler (MSVC) into a DEF file, applications that link to your DLL must also be built using the same version of MSVC so that the decorated names in the calling application match the exported names in the DLL's DEF file.
actxserver returns a handle to the primary interface to the object. Use this handle to reference the object in other COM function calls. You can also use the handle to obtain more interfaces to the object. For more information on using interfaces, see COM Object Interfaces.
actxserver returns a handle to the primary interface to the COM object. Use this handle to reference the object in other COM function calls. You can also use the handle to obtain more interfaces to the object. For more information on using interfaces, see COM Object Interfaces.
MATLAB can programmatically connect to an instance of a COM Automation server application that is already running on your computer. To get a reference to such an application, use the actxGetRunningServer function.
External function data sources are yet another variety of variable data source. These allow data to be specified by a user-defined function, provided in an external DLL or a Python script. We refer to these two types of external functions as native code external functions and Python external functions, respectively. This function is called repeatedly during the OrcaFlex simulation and is passed the current value of the variable data item. The function must then recalculate and update the value of the variable data item.
When OrcaFlex calls the external function for the first time it passes this value to the function. The function may use this value as its starting value; equally, it can ignore this value and substitute a different one.
This specifies the frequency with which OrcaFlex calls the external function to update the value of the variable data item. You can use the inner time step, the outer time step, or a user-specified time step. If you choose user-specified, then you must also supply a target time step; OrcaFlex will use the nearest whole multiple of the inner time step, and will report this value as the (non-editable) actual specified time step. 2b1af7f3a8