Why the DLL function performed by call library node fails when the Vi is reopened?

Development system

OS: Windows XP

LabVIEW: version 10.0

DLL: Custom

Compiler: Visual C++ 6.0

Function prototype: __declspec (dllexport) const char * test (void)

We have developed a DLL to use.  Compile the DLL itself.  The DLL includes a function test.  The test function validates the functional capabilities of the DLL.  I followed the examples online, and I used the tool to import shared library in LabVIEW.  The screw created use the call library node.

When I create a VI by calling the function in the DLL test customized by using the call library node the VI runs the test DLL function flawlessly.  I close the VI.  When I re - open the VI and run it, I get an error code of the DLL.  However, if I go on the schema and define the path of the DLL in the library call Configuration node once again the VI then runs the test DLL function perfectly again.

I have set the path of the DLL in the library call Configuration node everytime I open the VI.  The examples that I downloaded from the community don't require this.  What could be the missing DLL?  What Miss me?

I solved the problem.

I had create the DLL by using the following steps for VC 6.0:

1. new project

2. Select the Appwizard (DLL) MFC

3. Select the regular DLLS using the MFC shared DLLS

4 Yes for source file comments

5 finishing

The DLL must be on the VI search path.  The easiest way was to have the DLL in the same directory as the VI.

Tags: NI Software

Similar Questions

  • An array of LStrHandles to the breast to call library node grave Functio Resizeing down Subvi.

    Hello

    I try to resize a table of LStrHandles in a shared library. Here the code C - attached a picture of the appellant Subvi:

    / * Call library source file * /.

    #include
    #include "extcode.h".

    / * Typedefs * /.

    typedef struct {}
    long dimSize;
    LStrHandle elt [1];
    } TD1;
    typedef TD1 * TD1Hdl;

    long strArray (TD1Hdl arg1);
    long strArray (TD1Hdl arg1)
    {
    long err = 0, count = 2;

    ERR = DSSetHandleSize (arg1 (UHandle), count + (long) sizeof * sizeof (LStrHandle));
    {if (Err)}
    printf ("ERROR: 'DSSetHandleSize()': %ld\n", err);
    return err;
    };

    (* arg1)-> dimSize = (* arg1)-> dimSize;

    return noErr;

    }

    I know there is a lot of discussion, I read some and also tried the source code provided but somehow LabVIEW crashes. I don't know if it's valuable, but when I change the next line it don't crash:

    (* arg1)-> dimSize = (* arg1)-> dimSize;

    Thanks for any help,

    Johannes

    OS: RedHat

    LV: 8.2 teacher

    To be honest I'm not entirely sure why that would break but good process is much more complicated than what you have done. The crash probably can't function of C, but the return of the function such as LabVIEW tries to display data. DSSetHandleSize() doesn't boot the zone allocations in addition it of probably garbage that LabVIEW then tries to interpret as string handles and therefore crashes.

    You should also use NumericArrayResize() where possible because it supports various complications that can be difficult to deal with cross-platform programs. NumericArrayResize() use internal DSSetHSzClr() which initializes additional memory to 0. That would avoid the accident since LabVIEW interprets handles NULL as the default value for the data type, which would here be a string empty.

    #include "extcode.h".

    #if IsOpSystem64Bit

    uPtr uQ #define

    #else

    uPtr uL #define

    #endif

    typedef struct {}

    dimSize of Int32;

    LStrHandle Elm [1];

    } TDStrArr, * TDStrArrHdl;

    MgErr MyArrayFunc (TDStrArrHdl stop)

    {

    Int32 count = 4;

    LStrHandle p;

    MgErr err = noErr;

    / * Table could be non-empty, so have all of the items there are larger than we need * /.

    for (i = (* arr)-> dimSize - 1; i > = count; i--)

    {

    p = (* arr)-> Elm [i];

    If (p)

    DSDisposeHandle (p)

    }

    (* arr)-> dimSize = i + 1;

    / * resize the table handle to get enough space * /.

    ERR = NumericArrayResize (uPtr, 1, (UHandle *) & arr, count);

    If (err)

    return err;

    / * Fill in the data as desired * /.

    for (i = 0;! err & I)< count;="">

    {

    p = (* arr)-> Elm [i];

    #if! complicated

    ERR = NumericArrayResize (uB, 1, (UHandle *) & p, 1);)

    #else

    If (p)

    {

    ERR = DSSetHSzClr (p, sizeof (int32));

    }

    on the other

    {

    p = DSNewHClr (sizeof (int32));

    If (p)

    (* arr)-> Elm [i] = p;

    on the other

    ERR = mFullErr;

    }

    #endif

    If (! err)

    ERR = LStrPrintf (p, "% ld", i);

    }

    (* arr)-> dimSize = i;

    return err;

    }

    Rolf Kalbermatter

  • Why do I get an "internal error", just "Assertion failed" when calling createKeyword

    Here is my code.  It is called within a function that runs under LrTasks.startAsyncTask.  Calls to "Util.writeLog" confirm this createKeyword is called and never returns.

    () Util.Catalog:withWriteAccessDo

    "CreateKwUnderPerson,"

    function()

    Util.writeLog ('the call' createKeyword()'"")

    AKW = Util.catalog:createKeyword (name, {}, true, Nile, true)

    Util.writeLog ("'createKeyword"returned"()")

             end

    )

    I find it disconcerting that there is no more informative error message.   This seems to be a bug to Adobe, even if the problem where probably something I am doing wrong.

    The following text runs very well:

      catalog:withWriteAccessDo ("CreateKwUnderPerson", function()
          name = "test123"
          akw = catalog:createKeyword (name, {}, true, nil, true)
          end)
    

    However, if instead of the 'name' is assigned null, it then produces ' assertion failed!  So, check that the 'name' is a string.

    In addition, you use a debugger, for example, my toolbox for debugging or the IDE debugger described in another thread here?  They both take awhile to hang at the start, but they will save you a lot of time on the road, given the nature of Lua.

  • How to use the node function call library for a function in the dll with the data SUB type

    Hi all

    I would ask for your kind help

    I am facing a problem with the call library node.

    I have a C++ (stdcall) function, which has Sub as data type

    XXXX error code (hwnd, lid, getValue, * Sub data1, * Sub data2)

    data1 and data2 types are constantly changing based on the value of 'getValue '.

    Mainly I can use the call library node several times and adapt each node according to the types of data data1, data2 and extract the values and use in the code. Here is no question. Real question is:

    My question:

    How can I use a node of library time call and make a case according to the 'getvalue', who will control the data1, data2 data type. Here I really seeking solutions.

    My tests:

    I used varaints as entry to the libray call node of the data1, data2 and selected parameters in the call libraby node as "Adapt to type. Here labview just crashed.

    I appreciate your suggestions to feedbackand.

    Thank you

    Karine

    You must allocate enough space for data1 and data2, and then pass a pointer to this space. An easy way to do this is the function to initialize table. Set the U8 type and size for the number of bytes required. Pass this array to the function as a pointer of table data.

    After the function call returns, you need to extract the data in the table. You can do it manually, but a simple approach is to use the array of bytes to a string. Then, in a housing structure, use Unflatten chain to convert the string to the correct data type. This method also converts the "endianness" which will be probably necessary; Be sure to only set all entries for unflatten correctly.

  • What is the right way to specify the location of the shared library in an a .lvlib function call library function node?

    I'll have a bit of a problem with how to specify the location of library shared in a call library function node it is a VI that is part of a library of LV. Here's a little background which may help.

    I do a lot of measures using spectrometers photo from several manufacturers.  Someone in my company developed a C DLL library, which provides a simple API for all the different spectrometers. To facilitate this DLL to use in LabVIEW, I wrote a .lvlib that wraps all the functions.  When I want to use the API, I simply include the .lvlib file in my project that allows me to drag and drop the wrapper s VI on my block diagram. When I created the .lvlib of VI, I specified the path in the call library node. /. * so it will always look in the local application to the DLL directory when I run.

    The problem is, when I load demand, LabVIEW you asks for the location of the DLL even if it's just there in the local directory! I tried to put copies of the DLL in the directory with the .lvlib, but he still refuses to find the DLL loading.  What I am doing wrong?

    You should in this simple case enter the full path to the DLL by navigating to it. If the DLL is on the same volume/drive that the VI containing the call library node LabVIEW will be internally store the relative path from the VI to the DLL (but still show the absolute path). If you move the DLL and screw together (so the relative location of the DLL to the VI remains the same) LabVIEW will always find the DLL.

    I don't think that the lvlib would add nothing to that.

  • Trouble accessing a struct returned a DLL function

    I realize, this is a recurring theme on the forums, but I've not been able to find a thread that has successfully helped me to solve my problem, here's so I write.

    I work with a third party dll to get x, y data z to a device. I'm having problems when you try to use the following C function (via call library node):

    int ArmGetTipPosition (length_3D * position);

    where:

    typedef float length;

    Is it possible that your DLL is really a full group of 0?  Maybe you need to call another function in the DLL first to get something initialized?  If the cluster that you place in the node library call contains values non-null, this does affect the output?

  • When I use the library function node call in real time, is loaded only once for all or load the DLL whenever it is called?

    When I use the library function node call in real time, is loaded only once for all or load the DLL every time when it is called?

    I have a critical application in real time, in which I use a piece of DLL function developed in C++.  It is ok?  Make sure any senior developer?

    Thank you in advance.

    The user interface thread is the thread that is used to update the user interface. It's slow. And it's supposed to be that way because humans are slow.

    The call library function node can be configured as this thread to use in the configuration for it dialog box. Please visit the LabVIEW documentation on how to do this.

  • Call library function node, large table DLL by the way

    Hello

    I interfaced with success in most of the functions in a DLL, but it's trouble...

    Statement of header file:
    CORRTABLE * pDestCorrectionTable;

    Fundamental data type:
    struct {}
    long [65 * 65];
    long [65 * 65];
    long [65 * 65];
    }*;

    Call library Functio prototype node:
    long unsigned MC_get_corrtable (unsigned short int wSourceIndex, void * pDestCorrectionTable);

    The wrapper is generated automatically from the tools | Import | Shared library creates a cluster of 3 x 65 long. Shouldn't this created a 3 x 65 x 65 cluster? (but 256 is the maximum cluster size). That and tried all methods cause the node of the function of the library call crashing.
    What is the workaround?
    Thank you

    Al


  • How to implement a callback to the help function call library function node in LabView?

    I try to call a fuction from a SDK.dll library by using the node call library feature. The SDK has been provided to

    me and I don't have the source code, just the .dll and .h files.

    The SdkSetPropertyEventHandler function has a function of recall as one of its parameters. How to apply the

    callback using the NSI node? I'm a good programmer LabView but this is my first time using the library to call

    Function node. I read all the info I can find on the web site of NOR and the discussion Forum, but can not understand

    This one out. I'm using LabView 8.6.

    The deacribes SDK.h function as:

    Function: SdkSetPropertyEventHandler

    (SdkSetPropertyEventHandler) SdkError SDKAPI
    SdkCameraRef inCameraRef,
    SdkPropertyEvent inEvnet,
    SdkPropertyEventHandler inPropertyEventHandler,
    SdkVoid * context);

    //
    Description:
    Registers a callback function to receive the status
    change the notification events for the States of property on a camera.
    //
    Parameters:
    In: inCameraRef - designate the object camera.
    inEvent - designated one or all the events will be completed.
    inPropertyEventHandler - designate the pointer to the callback
    function to receive the camera property-related events.
    inContext - designated application information must be passed
    way to the callback function. All the data necessary to
    your application can be passed.
    Output: no
    //
    Returns: A sdk errors.
    -----------------------------------------------------------------------------*/

    A separate header called SDKTypes.h file contains the following data:

    typedef SdkUInt32 SdkPropertyEvent;
    typedef SdkUInt32 SdkPropertyID;
    typedef void SdkVoid;

    typedef struct __SdkObject * SdkBaseRef;
    typedef SdkBaseRef SdkCameraRef;

    /*-----------------------------------------------------------------------------
    SdkPropertyEventHandler
    -----------------------------------------------------------------------------*/
    typedef SdkError (SDKCALLBACK * SdkPropertyEventHandler))
    SdkPropertyEvent inEvent,
    SdkPropertyID inPropertyID,
    SdkUInt32 inParam,
    SdkVoid * context);

    Thanks for your help.
    Alejandro

    Andrew_E wrote:

    Hi Rolfk,

    You are absolutely right. This article describes what you were talking about? I'm just trying to get as much information as possible on this thread if the solution is easier to find for the future. Thank you.

    Yes, but I find the idea of using .net to call a LabVIEW VI as callback function C a bit as using a roll of Steam ironing your pants. Why do it? Well the steamroller has extra security guards that make it less likely that you'll break your pants in the process, but it's not elegant IMHO.

    Write a C DLL that translates between a C callback and a user event LabVIEW using the PostLVUserEvent() of the interface of the kernel to run LabVIEW function seems so eleganter for me. Yes, it's a bit of programming in C, but good!

    Rolf Kalbermatter

  • Memory from the Flushing call library function node

    I use the function call library (COLD LAKE) node to load some dll dynamically in a same vi.

    I use a loop for to send the DLL files or a table to COLD LAKE to load the different dll.

    For the first iteration, the COLD LAKE works very well, but for the second iteration and so on can not replace the output variable, and continue to repeat the result of the first iteration.

    Is there anyway to clear the memory of COLD LAKE, so that I will get the correct result for DLL 2nd and so on?

    I understand your message, you have different dll, which returns an array of LabVIEW.

    This table can be of different sizes according to the DLL you are calling.

    I think that you are having a general misunderstand about LV memory management. I think that your comments refer to the data space LV has allocated for the table, this has nothing to do with the DLL itself said!

    LV works memory about conservative. So if you allocated a data space, execution of a new of the same VI will try to reuse this dataspace. So the tables are not released if the VI will slow.

    That being said, the table itself will not reduce its size.

    The only question I have on this: you still have all the available values? If the new call returns the three values (out of 33), is the rest 30 items "the old value"?

    For ANSI C dll - it is common that the DLL also returns a scalar value "arraysize". If you got that, you can use the Array subset function to retrieve valid values.

    Norbert

  • When to call DSDisposeHandle when you have a DLL function acting as a dynamic data DS source extensible?

    Hello

    I have a dynamic function DLL acting as a data source within a LabVIEW application (see attachment) - I use DSNewHandle to dynamically allocate an array 2D handle storage via the Manager memory LV for arrays of arbitrary in application size data. I had assumed that these blocks of memory would be willing (Magic) when appropriate by the LabVIEW built in blocks that are sitting downstream, however, is not the case for treatment and the system LabVIEW memory usage continues to increase until you quit LabVIEW environment (not just if the offending application is stopped or closed).

    So my question is how and where to mop up the table used for buffers in the treatment of the application of the chain and how do I know when the buffers are really exhausted and not be re-used downstream (for instance two 2D paintings are first grouped into a 2D complex table by the re + im at the operator complex labview - is data memory out of this totally different stage of entries or is - a) modified version of the entry tables - if they are totally different and 2D to entry tables are not wired in all other blocks why the operator not have input data banks?)

    Maybe Im going to this topic in the wrong direction have the DLL data source dynamically allocates space data tables? Any advice would be welcome

    Concerning

    Steve

    So instead of doing:

    DLLEXPORT int32_t DataGetFloatDll(... , Array2DFloat ***p_samples_2d_i, ...)
    {
        ...
    
        if ( p_samples_2d_i )
        {        // *p_samples_2d_i can be non NULL, because of performance optimization where LabVIEW will pass in the same handle        // that you returned in a previous call from this function, unless some other LabVIEW diagram took ownership of the handle.        // Your C code can't really take ownership of the handle, it owns the handle for the duration of the function call and either        // has to pass it back or deallocate it (and if you deallocate it you better NULL out the handle before returning from the        // function or return a different newly allocated handle. A NULL handle for an array is valid and treated as empty array.
            *p_samples_2d_i = (Array2DFloat **) DSNewHandle( ( sizeof(int32_t) * 2 ) + ( sizeof(float) * channel_count * sample_count ) );
    
            // Generally you should first try to insert the data into the array before adjusting the size        // the most safe would be to adjust the size after filling in the data if the array gets bigger in respect to the passed in array        // and do the opposite if the adjusted handle happened to get smaller. This is only really important though if your C code can        // bail out of the code path because of error conditions between adjusting the handle size and adjusting the array sizes.        // You should definitely avoid to return from this function with the array dimensions indicating a bigger size than what the        // handle really is allocated for, which can happen if the array was resized to a smaller size and you then return because of errors        // before adjusting the dimension sizes in the array.         ........        (**p_samples_2d_i)->Rows = channel_count;
            (**p_samples_2d_i)->Columns = sample_count;
        }
    
        ...}
    

    You should do:

    DLLEXPORT int32_t DataGetFloatDll(... , Array2DFloat ***p_samples_2d_i, ...)
    {
        ...
        MgErr err = NumericArrayResize(fS /* array of singles */, 2 /* number of dims */, (UHandle*)p_samples_2d_i, channel_count * sample_count);
        if (!err)
        {        // Fill in the data somehow
           .....       
    
            // Adjust the dimension sizes        (**p_samples_2d_i)->Rows = channel_count;
            (**p_samples_2d_i)->Columns = sample_count;
        }
    
        ...}
    
  • The DLL call fails when DLL uses a wide range

    I call a C++ dll in LabVIEW 32-bit on Windows 7. I kept getting error 1097 and finally understood it is because the dll uses two large paintings of 5 MB each. The tables are initialized in the constructor of an object, malloc is not used, or whatever it is. If I do the smaller berries, then everything works fine.

    The problem is not difficult to work around, now that I know what is the cause, but can someone tell me why a dll using a lot of memory would be a problem? I feel that 10 MB is really a lot of memory to use on modern computers.

    OK, you can test the appeal of the DLL in a Visual Studio test harness?

    In addition, in case you haven't seen another 'DLL error 1097' son type, here are a few. The cause of 1097 in your case can be illuminated by a multitude of courses of troubleshooting:

    Call dll error 1097

    Error code coming 1097 in DLL call

    error 1097 after the call dll function that allocates memory inside

    1097 error in the transition from table from C++ DLL for LabView (seems very relevant, although long)

    I know there are a lot of reading, but there is a good chance that the magic trick is in one of these threads already. We will ride on the shoulders of their work.

  • Two parallel executions, calling a DLL function

    Hello

    Since this test takes about 6 hours to test my USE, I plan to use the parallel model to test 2 UUT at the same time in parallel.

    I implement the test code as a DLL of CVI.

    However, to my surprise, it seems that the steps that call a DLL function actually traveled in one series, not in parallel:

    Test 2 power outlets if one enters and executes a DLL works, the other waits for the first to complete its operation and return. While the other runs on the same copy of the DLL, so that the DLL global variables are actually shared between executions.

    So if a DLL will take 5 minutes to complete, two executions in the running at the same time take 10 minutes. This isn't a running in parallel in every way.

    What I want and expect also TestStand, was to completely isolate the copies of these two executions DLL such as test two casings could run at the same time the same DLL function by arbitrary executiong their copy of the function, completely isolated from one another.

    So they separated globals, discussions, etc., and two parallel jacks take 5 minutes to run a step, instead of 10.

    Such a scenario is possible?

    If not, how can I use my test in parallel (in truly parallel) when the use of 2-socket test?

    (1) Yes, he'll call the multiple executions in TestStand calling into the same dll in memory the same copy of this DLL. Thus dll called in this way must be thread-safe (that is written in a way that is safe for multiple threads running the code at the same time). This means usually avoiding the use of global variables among other things. Instead, you can store the thread shows in local variables within your sequence and pass it in the dll as a parameter as needed. Keep in mind all the DLLs your dll calls must also be thread-safe or you need to synchronize calls in other DLLs with locks or other synchronization primitives.

    1 (b) even if your dll are not thread-safe, you might still be able to get some benefits from parallel execution using the type of automatic planning step and split your sequence in independent sections, which can be performed in an order any. What it will do is allow you to run Test a socket A and B Test to another socket in parallel, and then once they are then perhaps test B will take place on one and test one run on the other. In this way, as long as each test is independent of the other you can safely run them in parallel at the same time even if it is not possible to run the same test in parallel at the same time (that is, if you can not run test on two Sockets at the same time, you might still be able to get an advantage of parallelism by running the Test B in one take during the tests in the other. See the online help for the type of step in autoscheduling for more details).

    (2) taken executions (and all executions of TestStand really) are threads separated within the same process. Since they are in the same process, the global variables in the dll are essentially shared between them. TestStand Station globals are also shared between them. TestStand Globals file, however, are not shared between runs (each run gets its own copy) unless you enable the setting in the movie file properties dialog box.

    (3) course, using index as a way to distinguish data access are perfectly valid. Just be careful that what each thread does not affect data that other threads have access. For example, if you have a global network with 2 elements, one for each grip test, you can use safely the decision-making of index in the table and in this way are not sharing data between threads even if you use a global variable, but the table should be made from the outset before start running threads , or it must be synchronized in some way, otherwise it is possible to have a thread tries to access the data, while the other thread is created. Basically, you need to make sure that if you use global data which the creation/deletion, modification and access in a thread does not affect the global data that the other thread use anyway in or we must protect these creation/deletion, modification and access to global data with locks, mutex or critical sections.

    Hope this helps,

    -Doug

  • Call library function node

    When using a call library function node, and the program came out, I get an error "has encountered a problem and needs to close" having to do with ntdll.  It does not stop the program from running properly, but it's annoying.  Any ideas?

    You should NOT specify the full path to a DLL system in the configuration dial the node of the library. This mess something in the newer versions of Windows. Instead just enter the name of the DLL only. It is sort of a bug in LabVIEW not automatically detect the system paths and shorten the path accordingly in itself, but this is how things have been for a long time and you just need to be a little careful.

    Also the return value must be really set up to be an integer of size of pointer, since a HANDFUL is really a pointer under Windows and that the first parameter is also better configured as such. The way you did works very well for LabVIEW 32 Bit but will misbehave in LabVIEW 64 Bit.

  • Crash when moving from a structure in a call library function node

    I am trying to use a type of Fortran (which I think is similar to a struct) in a LabVIEW call library function node.  I read a few remedies to this topic, but I'm not quite sure if I need to add the name of the parameter list of the node structure.  Now, when I run my VI it closed just LabVIEW entirely with no message.  I've attached the VI that I use and code source fortran, which compiles in my .dll.

    Any help is appreciated.

    Do you know if Fortran passes parameters by value or by reference?  I never used it.  A very quick search on the internet gives to think that the parameters must be passed by reference.  If this is the case, then you must pass the entire cluster as the parameter single, similar to Fortran statement.  You must also change the order of cluster to match the order in the Fortran statement.  Try the attached VI.

Maybe you are looking for