Scalar passing with call_external [message #59362] |
Thu, 20 March 2008 12:48  |
Brian Larsen
Messages: 270 Registered: June 2006
|
Senior Member |
|
|
All,
I am having a heck of a time with something here. I am trying to
understand the behavior of a C routine that I am trying to call from
IDL.
Given this C code: (ctest.c)
void ctest ( float a, float b, float *c, float v[3] )
{
float tmp;
tmp = a*b;
v[0] = tmp;
v[1] = a-b;
v[2] = a+b;
*c = 66;
}
And this IDL code: (ctest.pro)
make_dll, 'ctest', 'ctest', 'ctest', compile_directory = '.'
a = 5.
b = 3.
c = [7.]
v = fltarr(3)
ans = call_external('ctest.so', 'ctest', a, b, c, v, /auto_glue, value
= [1, 1, 0, 0])
print, ans, a, b, c, v
end
I expect the output to be:
<undetermined> 5.0 3.0 66.0
15.0 2.0 8.0
But instead I get:
IDL> .run ctest
-1073774376 5.00000 3.00000 7.00000
15.0000 2.00000 8.00000
So the root of the question is how do I pass scalar information back
out of the C routine to the IDL? As that looks to be failing. Anyone
have any useful tips here?
Cheers,
Brian
------------------------------------------------------------ --------------
Brian Larsen
Boston University
Center for Space Physics
|
|
|
Re: Scalar passing with call_external [message #59448 is a reply to message #59362] |
Wed, 26 March 2008 07:47  |
Trae
Messages: 23 Registered: May 2007
|
Junior Member |
|
|
On Mar 25, 6:56 am, Brian Larsen <balar...@gmail.com> wrote:
> I think that call_external() is saving some information
> somewhere. There is a flag to call_external() to stop that and that
> seems to help but not totally work... oddness.
Very odd. I haven't had these problems with call_external. Which
version of IDL are you using? I'm staying with an old version until
that beast of a dissertation is done. I wonder if call_external has
changed?
As a general note, using call_external, especially with the auto_glue
feature, is expensive computationally. It's usually best to roll your
own programs in IDL rather than try to import C codes. Unless you are
doing something ridiculously nerdy like generating Sobol numbers, or
something. :)
-Trae
|
|
|
Re: Scalar passing with call_external [message #59456 is a reply to message #59362] |
Tue, 25 March 2008 05:56  |
Brian Larsen
Messages: 270 Registered: June 2006
|
Senior Member |
|
|
Allan,
thanks. I have found that it works for me some too, but only in a new
idl session. I think that the problem is in repeated calls to the
routine. I think that call_external() is saving some information
somewhere. There is a flag to call_external() to stop that and that
seems to help but not totally work... oddness.
Brian
------------------------------------------------------------ --------------
Brian Larsen
Boston University
Center for Space Physics
|
|
|
Re: Scalar passing with call_external [message #59461 is a reply to message #59362] |
Tue, 25 March 2008 02:30  |
Allan Whiteford
Messages: 117 Registered: June 2006
|
Senior Member |
|
|
Brian Larsen wrote:
> All,
>
> I am having a heck of a time with something here. I am trying to
> understand the behavior of a C routine that I am trying to call from
> IDL.
>
> Given this C code: (ctest.c)
> void ctest ( float a, float b, float *c, float v[3] )
> {
> float tmp;
> tmp = a*b;
> v[0] = tmp;
> v[1] = a-b;
> v[2] = a+b;
> *c = 66;
> }
>
> And this IDL code: (ctest.pro)
> make_dll, 'ctest', 'ctest', 'ctest', compile_directory = '.'
> a = 5.
> b = 3.
> c = [7.]
> v = fltarr(3)
> ans = call_external('ctest.so', 'ctest', a, b, c, v, /auto_glue, value
> = [1, 1, 0, 0])
> print, ans, a, b, c, v
> end
>
> I expect the output to be:
> <undetermined> 5.0 3.0 66.0
> 15.0 2.0 8.0
>
> But instead I get:
> IDL> .run ctest
> -1073774376 5.00000 3.00000 7.00000
> 15.0000 2.00000 8.00000
>
> So the root of the question is how do I pass scalar information back
> out of the C routine to the IDL? As that looks to be failing. Anyone
> have any useful tips here?
>
> Cheers,
>
> Brian
>
> ------------------------------------------------------------ --------------
> Brian Larsen
> Boston University
> Center for Space Physics
Brian,
Nothing useful besides a fairly unhelpful "it worked for me"...
IDL> .r ctest
% Compiled module: $MAIN$.
1115947008 5.00000 3.00000 66.0000
15.0000 2.00000 8.00000
IDL> print,!version
{ x86 linux unix linux 6.2 Jun 20 2005 32 64}
with identical results on each of:
{ x86_64 linux unix linux 6.3 Mar 23 2006 64 64}
{ x86 linux unix linux 7.0 Oct 25 2007 32 64}
{ sparc sunos unix Solaris 6.2 Jun 20 2005 32 64}
{ sparc sunos unix Solaris 6.4 Mar 24 2007 64 64}
{ sparc sunos unix Solaris 7.0 Oct 25 2007 64 64}
which were chosen to be sufficiently random across architecture, version
number and 32/64 bit. It could be a specific compiler or architecture
thing I guess. If you happen to be using one of the above then I'd check
compilers rather than IDL.
It might also me that your compiler isn't overwriting the intermediate
shared object file, have you tried explicitly deleting it and running
the test again? Note also that usually you need to exit IDL and re-run
it to pick up any changes in a shared object file (unless you specify
/unload to call_external but that might be implicit when you use auto_glue).
Sorry if you've tried everything in the above paragraph, it's all I can
think of though.
Thanks,
Allan
|
|
|