Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

How to link to NI Traditional Drivers 'on the fly' - not static linking

Hi,
 
we've inherrited an imaging project that uses a 6601 card, it's used to give a PWM output to some LED panels and give a couple of other I/O lines. Currently the VC++ project links directly into to 'Traditional' NI-DAQ libraries, which means that when the program runs, Windows automatically wants to have the DLLs available.
 
What we want to do is to optionally link to the DLLs once the program is running, to give us the option of running on a PC where the card/drivers/DLLs are not installed. This is mainly for development work, and so that we can demo the software on a laptop, without having to always have the H/W with us.
 
Yes, I know we can install the NI-DAQ software, and run it without the card actually installed, so that the DLLs are there, but it's a big/messy install, so it would be nice to dynamically access the DLLs.
 
The other issue we have is the install. We ship our instrument out to customers with the 6601 card, and a FireWire card for them to install. However, it is counter-intuative for many of them to have to switch the PC on to install the NI-DAQ software BEFORE switching off to put the card in the machine, then switch on again to continue with the s/w install.  It makes the install process rather messy.  Also, the install seems to load a huge amount onto the target PC, so is there a 'stripped down' install program that has just the drivers for the 6601 and the appropriate DLLs - even though we seem to need 16 DLLs just to run a single card, why is this ?
 
Any help or suggestions would be appreciated.
 
Nigel
 
PS I guess it's already been mentioned that you can post to this board from FireFox ! ?
0 Kudos
Message 1 of 2
(3,131 Views)

Hi Nigel,

  In terms of a cut down traditional DAQ driver, unfortunately there isn't one and you must install in the correct order, since the driver covers multiple types of cards. THis way, when the BIOS recognises a new address in use, it allocates certain resources. Windows then gets involved once it's been booted, but our measurment and control services layer needs to get inbetween to actually identify the hardware type to Windows, otherwise it won't know what it's supposed to be installing and therefore which driver to use.

You could try making your own cut-down version, running through dependency walker on each .exe and DLL you need, and making sure that the card is correctly assigned out in Measurement and Automation explorer before you make you installer. Then you could in theory copy the data directory from underneath Measurement and Automation explorer, and make sure that hits the target. THat will then be specific to the serial number of the device you're using, so not actually that practical in the long run. The other issue would be in terms of support and debugging. With a reduced driver setup like you're asking for, you wouldn't be able to verify the card's behaviour away from your software, if someone had an issue with the measurements / control outputs.

In terms of late binding, the following c# tutorial uses C++ as a DLL as a means of calling to other DLL's without expressly linking them in.

http://www.codeproject.com/csharp/cscpplatebind.asp

so the code snippet is

struct map {
   int GRA, GRB, GRG, GRD;
   int LMR, RMR;
   int LCR, RCR;
   int LIR, RIR;
   char *LSR, *RSR;
};
   
typedef VOID (*MYPROC)(map*);
   
extern "C" __declspec(dllexport) __stdcall 
  void CallRemote(char *Library, char *Func, map *a) {
    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    hinstLib = LoadLibrary(Library);
   
    if (hinstLib != NULL) {
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, Func);
        if (NULL != ProcAdd) {
            (ProcAdd) (a);
        }
        FreeLibrary(hinstLib);
    }
}

The first structure is simply the declaration of the map structure in C++. The second type definition is that of the DLL function we're calling. It declares VOID as a pointer to a procedure, needing one parameter of type map (or more specifically, a pointer to the map type).

The function CallRemote uses the STDCALL calling convention as to make it easier to interact with .NET (it requires no altering of the stack). The _declspec(dllexport) convention is used to stop name mangling in the DLL when it is published. The function requires two strings, the library and function names, and the map reference.

CallRemote uses the LoadLibrary API to load the DLL file into memory, and then calls GetProcAddress to load the required function, returning the address in memory.

 

I hope that helps

Thanks

Sacha Emery
National Instruments (UK)

// it takes almost no time to rate an answer Smiley Wink
0 Kudos
Message 2 of 2
(3,123 Views)