10-06-2006 07:40 PM
10-09-2006 05:29 AM
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)