LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

import dll failed

Solved!
Go to solution

Hello everyone,

 

I have trouble loading in a .dll, which I created in MATLAB. I created a Wrapper .dll first. I tried to follow this tuturial:

https://forums.ni.com/t5/Example-Code/Walkthrough-for-Creating-a-MATLAB-DLL-That-Can-Be-Called-in/ta...

 

When I try to import it with the import Wizzard I get the following error

"Cannot generate library. The destination folder might be defined as read-only."

and no .lvlib file is created only the VIs.

Enclosed you'll find the .c file of the Wrapper and the report of the failed import.

 

 

Thanks for your help,

Jeremy

Download All
0 Kudos
Message 1 of 13
(4,076 Views)

I could solve this issue by recreating my main dll. However, now I have the proble that when I test my imported function i get the error d-1097:

Call Library Function Node in optimize_muscleWrapper.lvlib:wmlfoptimize muscle.vi->test_muscle_dll.vi

 

This dll I want to run is depending on other dlls. I am using an opensource software, OpenSim, which can be accesed via MATLAB through an API. While generating the dll, I added the dll of opensim via the MATLAB Compiler app. At least I think I manged to find them all. And also the matlab runtime should be included.

 

Could it be that I missed a dependency? Or what does this error mean?

 

Cheers,

Jeremy

0 Kudos
Message 2 of 13
(4,052 Views)

Error 1097 means that there was something happening while LabVIEW was executing the DLL that could and quite often will actually corrupt the integrity of the LabVIEW process. There are a lot of potential errors:

 

- buffer overflows

- stack corruption

- runtime exceptions (such as division by 0, null pointer or illegal pointer access, etc)

- bad programming in the C(++) code

 

When LabVIEW prepares the current thread to execute the external DLL function it puts up several additional security nets around the call by default. This includes storing the current stack pointer and adding so called trampolines around buffers passed to the DLL function. A trampoline is basically some extra memory before and after each buffer parameter (pointer, array, string) passed to the function and with that memory being initialized with a known pattern. It also installs an exception handler.

 

When this exception handler is triggered this results in the error 1097. And after the call, if there was no exception, it will check if the stack pointer is as it should be and if the trampoline memory areas still contain the known initialized data as it was before the call. If any of these don't match, something, somewhere, during the call to the external function was messing up somehow. There is not much more LabVIEW can do to detect what exactly happened, the corruption could have been caused by someone else than the called function but the likelihood of that isn't very big. So LabVIEW reports error 1097 to indicate that the system is most likely not anymore in a consistent state.

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 3 of 13
(4,042 Views)

Thank you for explaining the error message.

 

I just tried out the example that I mentioned. with the provided code of the turtorial. I also get the same error.

What could be the origin of this?

 

Thanks,

Jeremy

0 Kudos
Message 4 of 13
(4,018 Views)

Which example? From which tutorial? What same error? Your initial one or the 1097?

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 13
(4,010 Views)

Hi Rolf,

 

The example from the tutorial from my first post of this thread:

https://forums.ni.com/t5/Example-Code/Walkthrough-for-Creating-a-MATLAB-DLL-That-Can-Be-Called-in/ta...

 

It's the error 1097.

Sorry for not beeing clear.

 

0 Kudos
Message 6 of 13
(4,007 Views)

I tried another method to use the matlab code:

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000YGE2CAO&l=de-CH

Now I try to import it as a .NET Assembly and call the created class through the Invoke Node block (like in the link discribed)

 

Here I get the error d-1172:

 

Invoke Node System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
Inner Exception: System.Exception:

... MWMCR::EvaluateFunction error ...
No constructor 'org.opensim.modeling.Model' with matching signature found.
Error in => optimize_muscle.m at line 8.

... Matlab M-code Stack Trace ...
at
file C:\Users\gent\AppData\Local\Temp\gent\mcrCache9.0\optimi0\optimize_mus\optimize_muscle.m, name optimize_muscle, line 8.

<append><b>System.Exception</b> in Untitled 4

 

My guess would be that there is a missing dependency (e.g. a missing dll from the OpenSim).

Although, what I find strange is that the error only occours at line and not before, since I use the function:

 

import org.opensim.modeling.*

 

at line 4 and no error ocours there.

Does anyone know how to resolve this? Or does this help to resolve the issue for the other method to import a dll throught the import wizzard?

 

Thanks,

Jeremy

0 Kudos
Message 7 of 13
(3,999 Views)

You should at first try maybe to forget the import library wizard. It's not needed to be able to call DLLs from LabVIEW, it is just a tool that tries to help people who don't know how DLLs should be accessed to get started.

But unlike its name may indicate it can not do magic and often can NOT create the correct code needed to call the underlaying DLL. I never use it as I consider its advantages mostly limited to creating some (usually less than optimal) VI templates with preconfigured Call Library Nodes. Those Call Library Nodes regularly are not configured fully correctly, simply because the C syntax in the header file is not able to convey all the information that is often needed. That information is located in documentation files that hopefully come with the DLL and computers are still pretty bad at interpreting prosa text.

 

In addition, the Import Library Wizard simply translates the DLL function call into a VI interface which is often more than suboptimal. A proper LabVIEW VI should not burden the user with typical C style programming details and it is the task of the VI creator to translate that properly. However the Import Library Wizard can't really do much of that, since it simply can't know that a size parameter might be related to a pointer parameter.

 

So try to forget the Import Library Wizard for a moment. It's by no means necessary and from what I can see from your original wrapper, the API is fairly simple too.

 

I would change the prototype even to:

 

 

int wmlfoptimize_muscle(double cF_cor[], double ctheta0, double ctheta1, double ctheta2, double ctheta3, double cF_actual[], double cF_offline[], double cM_controller[], double ckp, double ca, double cb, char cModelFile[]);

 

 

Then configure the Call Library Node as follows:

 

return value: Numeric, 32-bit signed integer

cF_cor: Array, double precision, minimum size: 8, Pass as Data Pointer

ctheta0: Numeric, double, Pass by value

ctheta1: Numeric, double, Pass by value

ctheta2: Numeric, double, Pass by value

ctheta3: Numeric, double, Pass by value

cF_actual: Array, double precision, minimum size: 8, Pass as Data Pointer

cF_offline: Array, double precision, minimum size: 10, Pass as Data Pointer

cM_controller: Array, double precision, minimum size: 3, Pass as Data Pointer

ckp: Numeric, double, Pass by value

ca: Numeric, double, Pass by value

cb: Numeric, double, Pass by value

cModelFile: String, Pass as Data Pointer

 

You don't specifically need the minimum size for the cF_actual, cF_offline and cM_controller, but you need to make sure in your VI to pass in array which contain enough values to satisfy these lengths. If you use the minimum size parameter in the Call Library Node setup but pass in a to small array, LabVIEW will simply resize the array to the configured minimum size, adding zero values to the array. This still will of course probably cause wrong results but it won't crash the VI (or create 1097 errors).

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 8 of 13
(3,991 Views)

Hi Rolf,

 

Thanks for sugessting the direct way to use c shared dlls. However, I still get the same error 1097. As I mentioned before, I also used .net assembly blocks to load in the dotNet dll. Here I get the error at line 8 in my matlab code where I create a object which is utilizes the 3rd party dll (OpenSim). So I was wondering if there might be another problem?

As mentioned before I have included the opensim dll while creating my dll. I think at least that I have included all, there are many of them. Maybe my dll does not find the 3rd part dlls?

Am I here on the wrong path and you think the error could come from somwhere else?

0 Kudos
Message 9 of 13
(3,964 Views)

I haven't seen the Matlab code (nor would I be really able to analyze it) but it's quite likely that Matlab tries to instantiate the OpenSim interface dynamically (as it is probably located in its own collection of shared libraries).

 

That of course means that Windows needs to be able to locate the OpenSim shared libraries. And that means they have to be in a global, by Windows findable location. And there are not that many options for that. Just adding the OpenSim DLLs to the build specification is not enough. LabVIEW knows nothing about these secondary DLLs and while your build specification may include them, it will not do anything with them other than copying them to whatever location you specify. Windows on the other hand knows nothing about that build specification and only searches in specific locations for DLL dependencies, with the most common being:

 

- if a DLL with the desired name is already loaded into the process space it uses that (except when it also contains a version manifest for SxS DLL loading and it is not the same version)

- the application executable directory (where your myapp.exe is located)

- the Windows System directory

- the Windows directory

- any directory that is listed in the PATH environment variable

 

If Windows can't find the DLL in these locations, LoadLibrary simply fails and if the calling code fails to check for that error and simply tries to use the invalid library handle, an exception occurs (NULL Pointer reference or similar). That the Matlab DLL causes an exception rather than a runtime error code isn't really neat, but not very uncommon from lots of software.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 10 of 13
(3,958 Views)