Hello,
Disclaimer: I am a newbie at all things C, including CFFI. Thus what I am trying to do may not be possible. The following is on Windows 7. I use clisp on cygwin.
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library is shipped with Tektronix software.
The manual gives examples of using the library using C++, and I am trying to follow the first example. To me it looked pretty much like C - no objects, templates at least.
Problem: defcfun cannot find the function.
Here is the example code:
#include <visa.h> #include <stdio.h> #include <memory.h> // This example opens a specific GPIB device, does an *idn query // and prints the result. int main(int argc, char* argv[]) { ViSession rm = VI_NULL, vi = VI_NULL; ViStatus status; ViChar buffer[256]; ViUInt32 retCnt; // Open a default session status = viOpenDefaultRM(&rm); <--------------- I want to access this function if (status < VI_SUCCESS) goto error; // Open the GPIB device at primary address 1, GPIB board 8 status = viOpen(rm, “GPIB8::1::INSTR”, VI_NULL, VI_NULL, &vi); if (status < VI_SUCCESS) goto error;
... etc
My cffi code is: (cffi:defctype ViSession :int) (cffi:defctype ViStatus :int)
(cffi:defcfun ("viOpenDefaultRM" vi-open-default-rm :library tek-visa) ViStatus (rm ViSession))
And the library is defined thus: (cffi:define-foreign-library tek-visa (:windows *VISA-lib*)) ;; *VISA-lib* contains path to the library
(cffi:use-foreign-library tek-visa)
defcfun gives warning that the foreign function does not exist.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
I tried using these (and some variants), but got the same message.
Now, this is a Windows library, and clisp is on Cygwin. Could that be the problem? Any other thoughts?
Thank you,
Mirko
Hello Mirko,
On Tue, Jun 25, 2013 at 1:56 AM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library is shipped with Tektronix software.
I'm surprised loading it works. That sounds like a static library.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
This looks like the stdcall calling convention. (See "Name-decoration convention" in http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.71).aspx.) Passing ":convention :stdcall" to DEFCFUN should work.
Cheers,
-- Luís Oliveira http://kerno.org/~luis/
On Tue, Jun 25, 2013 at 4:22 AM, Luís Oliveira loliveira@common-lisp.netwrote:
Hello Mirko,
On Tue, Jun 25, 2013 at 1:56 AM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library
is
shipped with Tektronix software.
I'm surprised loading it works. That sounds like a static library.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
This looks like the stdcall calling convention. (See "Name-decoration convention" in < http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.71).aspx%3E.) Passing ":convention :stdcall" to DEFCFUN should work.
As a side point, I'm not sure if cffi-libffi works with stdcall. I think I put the code in, but having nothing to test it on, I have no idea if it works. If you have some structures-by-value functions to call, it would be good to test it (but you'll have to do the debugging if it fails).
Liam
On Tue, Jun 25, 2013 at 4:22 AM, Luís Oliveira loliveira@common-lisp.netwrote:
Hello Mirko,
On Tue, Jun 25, 2013 at 1:56 AM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library
is
shipped with Tektronix software.
I'm surprised loading it works. That sounds like a static library.
You were correct. It did not. I found a dynamically loaded library (dll), and successfully linking to it.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
This looks like the stdcall calling convention. (See "Name-decoration convention" in < http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.71).aspx%3E.) Passing ":convention :stdcall" to DEFCFUN should work.
Now that I linked to the correct library, defcfun works: I already managed to crash clisp a few times due to access violation errors. Now I'm off to learn about passing pointer arguments
Cheers,
-- Luís Oliveira http://kerno.org/~luis/
If anything worth sharing comes out of this effort, I may put it out into the world.
Mirko
On Tue, Jun 25, 2013 at 5:43 PM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
Passing ":convention :stdcall" to DEFCFUN should work.
Now that I linked to the correct library, defcfun works: I already managed to crash clisp a few times due to access violation errors. Now I'm off to learn about passing pointer arguments
Cool. Make sure you're using the right calling convention, though.
Cheers,
-- Luís Oliveira http://kerno.org/~luis/
On Tue, Jun 25, 2013 at 3:22 AM, Luís Oliveira loliveira@common-lisp.net wrote:
On Tue, Jun 25, 2013 at 1:56 AM, Mirko Vukovic mirko.vukovic@gmail.com wrote:
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library is shipped with Tektronix software.
I'm surprised loading it works. That sounds like a static library.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
.lib is the naming convention for an MSVC import library, forwarding to a .dll. In cygwin and mingw it is usually named .dll.a. See the I type, and the __imp__ prefix.
With gnu binutils you can find the matching dll (they have versioned names, and no symlink support) via dllimport -I libname
-- Reini Urban http://cpanel.net/ http://www.perl-compiler.org/
On Wed, Jun 26, 2013 at 8:40 AM, Reini Urban rurban@x-ray.at wrote:
On Tue, Jun 25, 2013 at 3:22 AM, Luís Oliveira loliveira@common-lisp.net wrote:
On Tue, Jun 25, 2013 at 1:56 AM, Mirko Vukovic mirko.vukovic@gmail.com
wrote:
I am trying to link to a VISA library (VISA is used to control data acquisition instruments), visa32.lib compiled for Windows. The library
is
shipped with Tektronix software.
I'm surprised loading it works. That sounds like a static library.
Using `nm' I did find: 00000000 I __imp__viOpenDefaultRM@4 00000000 T _viOpenDefaultRM@4
.lib is the naming convention for an MSVC import library, forwarding to a .dll. In cygwin and mingw it is usually named .dll.a. See the I type, and the __imp__ prefix.
With gnu binutils you can find the matching dll (they have versioned names, and no symlink support) via dllimport -I libname
Did you mean dlltool (http://www.gnu.org/software/binutils/)
-- Reini Urban http://cpanel.net/ http://www.perl-compiler.org/