Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

exported functions in ivi scope dlls

I'm planning to send a command to an IVI scope (to unlock the front panel) in c++ in measurement studio by loading the dll (with afxloadlibrary), then using GetProcAddress to get a function pointer to the WriteInstrData function in the dll.
I'm developing this with the tektronix driver tktds2x0, but needs to be applicable to any IVI scope driver (that has an WriteInstrData function). All the exported functions are prefixed with this driver identity,
eg tktds2x0_WriteInstrData(...)
This doesn't make sense to me! I would expect it to be exported as just
WriteInstrData(...)
Could someone please explain why the functions are exported with this naming convention? How does the IVI framework use these specific ivi scope drivers if the functions are all exported with driver specific names?
Thanks
0 Kudos
Message 1 of 9
(4,210 Views)
The problem with exporting the functions without a prefix is that you wouldn't be able to use two specific drivers in the same application - you'd get compile errors because of duplicate function declarations, and link errors because of duplicate function definitions. Remember that IVI drivers are often used without the presence of a class driver at all. As to how the class drivers are able to make calls to those functions even though they all have unique names - when you initialize a class driver session, the class driver determines the specific driver prefix and dll from the IVI Config Store, loads the dll, and then builds the function names on which to call GetProcAddress based on the driver prefix.
0 Kudos
Message 2 of 9
(4,203 Views)
Thanks. That's good to know. If you can give me any suggestions for IVI documentation, I would be grateful.
 
ALso, I am having problems getting the code to do this to work

 m_pScope = new CNiIviScope("210scope", true, false);
 ViSession specificDriverSession = m_pScope->GetSpecificDriverSession(); 

 HINSTANCE hDLL = AfxLoadLibrary(m_strDriverPath); // m_strDriverPath obtained from the config store
 if (!hDLL) {
  AfxMessageBox("Can't find the DLL for the IVI scope selected"); 
  return;
 }

 typedef ViStatus (*WRITEFUNC)(ViSession,ViConstString);

 WRITEFUNC pFunc = (WRITEFUNC)GetProcAddress((HMODULE)hDLL,"tktds2x0_WriteInstrData");
 if (!pFunc) {
  AfxFreeLibrary(hDLL);
  return;
 }
 pFunc(specificDriverSession, ":LOCK NONE");  // ***ERROR HERE***
 AfxFreeLibrary(hDLL);
 m_IsUnlockable = true;
 
It gives the runtime error:
The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
 
Is there anything obviously wrong with this?
 
The implementation in tktds2x0.c is
ViStatus _VI_FUNC tktds2x0_WriteInstrData (ViSession vi, ViConstString writeBuffer)  
{  
    return Ivi_WriteInstrData (vi, writeBuffer);   
}  
 
I would like to know what the '_VI_FUNC' is all about. I haven't seen that syntax before. Could this be the problem? Does my function pointer type not match that exported in the dll?
 
many thanks
0 Kudos
Message 3 of 9
(4,200 Views)
You are exactly right. _VI_FUNC is a VISA-defined constant that resolves the calling convention based on the platform for which it's running. You need to add that to your typedef. For Win32, _VI_FUNC is equivalant to _stdcall. The default calling convention is _cdecl, which is why you're getting the runtime error. _cdecl and _stdcall push function args to the stack in opposite order.
 
Your typedef should look like this:

typedef

ViStatus (_VI_FUNC *WRITEFUNC)(ViSession, ViConstString);

Message 4 of 9
(4,196 Views)

It works now. THank you so much!

ANy suggestions about where I can start looking for more documentation, other than the IVI help provided by NI, which IMHO is poor and lacking examples? I have found the NI website to be almost useless for IVI issues.

0 Kudos
Message 5 of 9
(4,194 Views)
What documentation are you looking at that you find lacking? Are you referring to the help that is part of the C++ API's, or to additional IVI help documents? Have you looked at the help documents in C:\program files\National Instruments\ivi\Help?
0 Kudos
Message 6 of 9
(4,191 Views)
actually it's a while since I've looked there, and this is more useful than it first was when I started using IVI! Thanks! However, There seems to be a lack of cohesion with the documentation. I have found it a real struggle to FIND the documentaion.
0 Kudos
Message 7 of 9
(4,170 Views)
The IVI documentation can easily be found under Start>Programs>National Instruments>IVI. An information about IVI in general can be found on http://www.ni.com/ivi/
.
 
Thanks,
Vesna
0 Kudos
Message 8 of 9
(4,160 Views)
Re documentaion - here is my latest 'struggle'. I don't think this is satisfactory these days:

Using CNiIviFgen classes in measurement studio 6
In the FgenArbitrary member, there are some data items listed:
double Gain[] The factor by which the function generator scales the arbitrary waveform data.

OK so I try, m_pFgen->Arbitrary.Gain = 2.0;
Gives the compile error 'SetGain does not take 1 parameter'
There are no functions in the documentation called SetGain.
SO I find and look in the header file, only to see:

// Specifies whether the generated signal appears at the output connector.
GET_PUT_CH_PROPERTY(bool, Enabled, OUTPUT_ENABLED);

So there's some funny macro being used here. Back up to the top of the header:

#define GET_PUT_CH_PROPERTY(type, name, id)\
__declspec(property(put=Set##name,get=Get##name)) type name[];\
void Set##name (const CString& ch, const type& value) { impl.Set(ch,IVIFGEN_ATTR_##id,value); }\
type Get##name (const CString& ch) const {\
type value;\
impl.Get(ch,IVIFGEN_ATTR_##id,value); \
return value;\

Now, this is difficult code to understand (especially as there are 3 similar versions). I eventually work out (from the error generated in NI spy) that you need to supply a channel name. Then it works fine.Perhaps that's what the [] after Gain was all about - who knows - it doesn't say... This has wasted hours, and all because the documentation is POOR. Come on NI, spare a thought for 'newcomers' who just want easy to follow documentation. And how about some examples. One simple Fgen example is all they bothered to supply with measurement studio 6
0 Kudos
Message 9 of 9
(4,143 Views)