05-10-2012 05:41 AM
I have to control some electric loads and power supplies over GPIB. We use Qt 4.7.4 with MinGW 4.4 (32-bit) on Windows 7 64-bit.
The packet NI-488.2 GPIB Drivers packet 3.0.2 for Windows 7 64-bit is installed. The GPIB Troubleshooting Utility tool shows "pass" and the Measurement & Automation application can connect to the board and talk to an intrument. So far so good.
Now I want to write an application to use the NI4882.dll (3.0.0.49153). Unfortunately, there are just object files for Microsoft and Borland compilers and no lib file.
So we generate a def file from the ni4882.dll with:
pexports -h ni4882.h ni4882.dll > ni4882.def
-ni4882.def-
LIBRARY NI4882.dll
EXPORTS
?compareVersion@nGPIBAPI_NI4882@@YGXABVtSSVersion@@0AAJPBD@Z
?getCurrentVersion@nGPIBAPI_NI4882@@YG?AVtSSVersion@@AAJ@Z
?getOldestCompatibleVersion@nGPIBAPI_NI4882@@YG?AVtSSVersion@@AAJ@Z
AllSpoll@12
DevClear@8
DevClearList@8
...
--
Then generate the lib with:
dlltool -k -D ni4882.dll -d ni4882.def -l libni4882.a
Now, I've build a small test program in Qt.
-.pro file-
INCLUDEPATH += $$PWD/include
LIBS += $$PWD/lib/libni4882.a
--
-.cpp file-
#include "ni4882.h"
...
void MainWindow::Init()
{
int dd = idev(0,3,0,T10s,1,0);
if(Ibsta()&ERR)
{
Err(tr("Unable to open board:ibdev=%1").arg(dd));
}
if( ibonl(0,0)&ERR)
{
Err(tr("Unable to close board"));
}
}
void MainWindow::Err(QString message)
{
switch(Iberr())
{
case 0:
{
message.append("(EDVR - System error)");
} break;
...
}
qDebug("Error : %s\nibsta = 0x%x iberr = %d\n",
(unsigned int)Ibsta(), (int)Iberr());
}
--
The source code will be compiled and linked without an error.
But if I run it, the output is:
Error : Unable to open board: ibdev=32768 (EDVR - System error)
ibsta = 0x8000 iberr = 0
Error : Unable to close board (EDVR - System error)
ibsta = 0x8000 iberr = 0
So, the question is: What is wrong? Why do I always receive this EDVR error. I also tried SendIFC(0) with the same result.
With the GPIB Interactive Control tool, I can communicate with my instrument and the NI I/O Trace logs it. But I can't see logs in the Trace tool from my application. Is this an indication?
Any ideas?
Marko
Solved! Go to Solution.
05-14-2012 12:27 PM
Hi Marko,
Currently NI4882.dll only works when using our provided object file. This will prevent you from using NI4882.dll with Qt. That limitation will be removed in the next release.
Are you making a 32 bit application? If so you can use the gpib-32.dll which does not have the same limitation.
Please let me know if you have any questions.
05-15-2012 02:54 AM
Hi Justin,
thank you for your answer.
I don't understand why it's necessary to use you *.obj file instead of creating a *.a file as described above? What is the difference?
So I try to use the GPIB-32.dll.
Regards
Marko
05-15-2012 11:32 AM
Hi Marko,
It shouldn't be necessary to use our object file. This is something we are addressing in the next release. Hopefully gpib-32.dll will work for you.
12-17-2012 06:46 AM
Hi to all,
after some questions about using the GPIB library with Qt, I've written a step by step description to create object files for MinGW:
1. Create a folder and copy the "gpib-32.dll" from the "C:\Windows\System32" ("C:\Windows\SysWOW64" in Win7) to this folder.
2. Copy "ni488.h" from "c:\Program Files (x86)\National Instruments\Shared\ExternalCompilerSupport\C\include\". (Not ni4882.h!)
3. Load PExports (my version is 0.44) and put the exe in your folder to. I do not have a URL to load this tool but should be easy to find. It's freeware.
4. Copy dlltool.exe from "c:\QtSDK\mingw\bin\" to your folder.
5. Create a batch file "1 - build def file.bat" with the content: "pexports -h ni488.h gpib-32.dll > gpib.def"
6. Create a batch file "2 - build lib file.bat" with the content: "dlltool -k -D gpib-32.dll -d gpib.def -l libgpib.a"
7. Start the batch file "1 - build def file.bat" to create the def file "gpib.def"
8. Start the batch file "2 - build lib file.bat" to create the library file "libgpib.a"
9. Copy "gpib-32.dll" and "libgpib.a" to your software project. I created the subfolder "lib" and copied the files into.
10. Copy "ni488.h" to your software project. I created the subfolder "include" and copied the file into.
11. Into your PRO file type:
# #####################################################################
# Include the NI 488.2 library
# #####################################################################
INCLUDEPATH += $$PWD/include
HEADERS += include/ni488.h
LIBS += $$PWD/lib/libgpib.a
12. In your source code type:
#include "windows.h"
#include "ni488.h"
bool InitializeGPIBBoard( )
{
bool isStarting = false;
int boardID; /** @brief Board id. */
QString boardName; /** @brief Board name. */
int boardDescr; /** @brief Board descriptor. */
// Get board ID
SendIFC(boardID);
if( ThreadIbsta() & ERR )
{
ErrorHandling(tr("Unable to open board"));
return isStarting;
}
// Open and initialize a board or a user-configured device descriptor
wchar_t *aName = new wchar_t[boardName.size()+1];
m_para.boardName.toWCharArray( aName );
aName[boardName.size()] = 0;
m_para.boardDescr = ibfind( aName );
delete []aName;
// The board is the System Controller.
if( ibconfig( boardDescr, IbcSC, 1 ) & ERR )
{
ErrorHandling(tr("Unable to set the board to System Controller"));
return isStarting;
}
// Assert interface clear.
if( ibsic( boardDescr ) & ERR )
{
ErrorHandling(tr("Assert interface clear"));
return isStarting;
}
// aso.
isStarted = true;
return isStarted;
}
13. Be happy! 🙂
I hope that helps. If you have problems, please write me a message or post on this board thread.
Gruß und viel Erfolg!
Marko
12-17-2012 10:58 AM
Thanks for posting to share your experience with others. As of NI-488.2 3.1 you should be able to access ni4882.dll without the use of the NI object file as well. This opens up the possibility of using it with 64-bit applications.
-Jason Smith
12-17-2012 11:23 AM
Jason, thanks for your remark.
I use NI-488.2 3.0.2. Cause of project restrictions it is not possible to use a newer version.
So guys, use the newest library version if possible.
Bye
Marko
12-17-2012 01:12 PM
Hi Marko,
i can´t create the libgpib.a
can you send me the file?
thanks
03-06-2014 03:22 AM
OK, I sure kuoyaoming managed it throw,
But if there is anyone that get the same problem...
I failed to create the .a file too, and get workaround by loading the gpib-32.dll dynamically.
Some code:
gpib.h:
#include <windows.h> typedef int _stdcall (*ibdevPtr) (int boardID, int pad, int sad, int tmo, int eot, int eos); typedef int _stdcall (*ibwrtPtr) (int ud, PVOID buf, long cnt); typedef int _stdcall (*ibrdPtr) (int ud, PVOID buf, long cnt); class GPIB482 { public: GPIB482(); private: int loadDllDynamically(); HINSTANCE hLib; ibdevPtr ibdev; ibwrtPtr ibwrt; ibrdPtr ibrd; }; #endif // GPIB482_H
gpib.cpp
GPIB482::GPIB482() { loadDllDynamically(); //Now, for the [dummy] example: int dev = (ibdev)(0, 1, 0, 11, 1, 0); (ibwrt)(dev, "GOOD", 4); } int GPIB482::loadDllDynamically() { local_dll_adr = "C:/Windows/System32/gpib.dll"; hLib = LoadLibraryA(local_dll_adr.toStdString().c_str()); if (hLib == NULL) { QMessageBox::warning(0,"","Failed load lib"); return -ENOSYS; } ibdev = (ibdevPtr) GetProcAddress(hLib, "ibdev"); if (ibdev == NULL) { QMessageBox::warning(0,"","Failed find ibdev"); return -ENOSYS; } ibwrt = (ibwrtPtr) GetProcAddress(hLib, "ibwrt"); if (ibwrt == NULL) { QMessageBox::warning(0,"","Failed find ibwrt"); return -ENOSYS; } ibrd = (ibrdPtr) GetProcAddress(hLib, "ibrd"); if (ibrd == NULL) { QMessageBox::warning(0,"","Failed find ibrd"); return -ENOSYS; } return SUCCESS; }
That's all,
Hope i been helping for someone...
Aviad
06-17-2014 02:42 PM
Anyone using MarkoSat's method -- make sure to include "windows.h" before "ni488.h". This appears to be working with the new version of pexports (0.46).