Calling a dll c function returning a pointer 
Author Message
 Calling a dll c function returning a pointer

Hi,


subroutine fun1(input1)
      interface
         real*4 function fun2(input2)
!dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
            real*4 input2
         end function fun2
      end interface

      real*4 a,b
      a = 0
      if(input1.eq.0) then
         b = fun2(a)
      end if

      return
end

But, when I changed the C function so it's returning a pointer to
float instead of a float:

subroutine fun1(input1)
      interface
         function fun2(input2)
!dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
            real*4, pointer::fun2(:)
            real*4 input2
         end function fun2
      end interface

      real*4 a,b
      real*4, pointer::fun2_output(:)

      a = 0

      if(input1.eq.0) then
         fun2_output => fun2(a)
         b = fun2_output(0)
      end if

      return
end

I got:

test.obj : error LNK2001: unresolved external symbol _fun2
Debug/project.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

project.dll - 2 error(s), 0 warning(s)

Please help me! I've searched the entire internet for an answer...



Sun, 23 Aug 2009 15:46:28 GMT  
 Calling a dll c function returning a pointer
| Hi,
|
(snip)
| But, when I changed the C function so it's returning a pointer to
| float instead of a float:
|
| subroutine fun1(input1)
|      interface
|         function fun2(input2)
| !dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
|            real*4, pointer::fun2(:)
|            real*4 input2
|         end function fun2
|      end interface
|
|      real*4 a,b
|      real*4, pointer::fun2_output(:)
|
|      a = 0
|
|      if(input1.eq.0) then
|         fun2_output => fun2(a)
|         b = fun2_output(0)
|      end if
|
|      return
| end
|
| I got:
|
| test.obj : error LNK2001: unresolved external symbol _fun2
| Debug/project.dll : fatal error LNK1120: 1 unresolved externals
| Error executing link.exe.

For the start, you haven't shown us the C code.

There are two separate issues, though: linking problem (which would
be simple to solve) and the incompatibility problem (which requires
a bit more).

As for the linking problem: you're apparently using CVF or IVF.
I can't tell what exactly happened, but here are some tips:

1) Ensure that the C function is
   a) marked with extern "C" in the code
   b) exported from the dll (via __declspec(dllexport) or .def file)
2) Check its exact alias using "Dependency walker" tool (it's in
   CVF or VS program groupm, or in http://www.dependencywalker.com)
   or, from command line:
   dumpbin /exports yourdll.dll
3) Of course, ensure that you link the fortran project with dll's
   export library (yourdll.lib)

However, there's another problem: namely, the C and Fortran prototypes

float* fun2(float);  and

real*4, pointer::fun2(:)

do NOT match. Fortran pointer to an array is much more complex stuff
that mere float*. This will crash or misbehave in run-time even when
you manage to get the linking right.

There are numerous ways to redesign it, but I'm reluctant to delve
into details until you tell us what the C function does and who
is supposed to allocate the memory for the pointer. The cleanest
path would probably be along these lines:

extern "C" void __declspec(dllexport) fun2(float f, float* r);
....
interface
  subroutine fun2(f, r)
  !DEC$ATTRIBUTES C, ALIAS: "_fun2":: fun2
  real, intent(in):: f
  real, intent(out):: r(*)
  end subroutine
end function

--
 Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.



Sun, 23 Aug 2009 16:17:18 GMT  
 Calling a dll c function returning a pointer

Quote:

> (snip)
> | But, when I changed the C function so it's returning a pointer to
> | float instead of a float:
> |
> | subroutine fun1(input1)
> |      interface
> |         function fun2(input2)
> | !dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
> |            real*4, pointer::fun2(:)
> |            real*4 input2
> |         end function fun2
> |      end interface
> |      real*4 a,b
> |      real*4, pointer::fun2_output(:)
> |      a = 0
> |      if(input1.eq.0) then
> |         fun2_output => fun2(a)
> |         b = fun2_output(0)
> |      end if
> |      return
> | end
> | I got:
> | test.obj : error LNK2001: unresolved external symbol _fun2
> | Debug/project.dll : fatal error LNK1120: 1 unresolved externals
> | Error executing link.exe.
> For the start, you haven't shown us the C code.

Yes, that would help a lot.

Quote:
> There are two separate issues, though: linking problem (which would
> be simple to solve) and the incompatibility problem (which requires
> a bit more).
> As for the linking problem: you're apparently using CVF or IVF.
> I can't tell what exactly happened, but here are some tips:
> 1) Ensure that the C function is
>    a) marked with extern "C" in the code

extern "C" is used when compiling C code with a C++ compiler,
usually when mixed with C++ code.  Otherwise, is the C function
named _fun2, as the message indicates?

Quote:
>    b) exported from the dll (via __declspec(dllexport) or .def file)
> 2) Check its exact alias using "Dependency walker" tool (it's in
>    CVF or VS program groupm, or in http://www.dependencywalker.com)
>    or, from command line:
>    dumpbin /exports yourdll.dll
> 3) Of course, ensure that you link the Fortran project with dll's
>    export library (yourdll.lib)
> However, there's another problem: namely, the C and Fortran prototypes
> float* fun2(float);  and
> real*4, pointer::fun2(:)
> do NOT match. Fortran pointer to an array is much more complex stuff
> that mere float*. This will crash or misbehave in run-time even when
> you manage to get the linking right.

Note that functions returning pointers are a little complicated,
even in C code.  The usually choices are returning a pointer to
static data, returning a pointer to one of the arguments (or some part
of an argument), or allocating memory and returning a pointer to it.
The last requires the caller to free the memory, often inconvenient.

Quote:
> There are numerous ways to redesign it, but I'm reluctant to delve
> into details until you tell us what the C function does and who
> is supposed to allocate the memory for the pointer. The cleanest
> path would probably be along these lines:

-- glen


Sun, 23 Aug 2009 17:07:48 GMT  
 Calling a dll c function returning a pointer
|
|| (snip)
||| But, when I changed the C function so it's returning a pointer to
||| float instead of a float:
|||
||| subroutine fun1(input1)
|||      interface
|||         function fun2(input2)
||| !dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
|||            real*4, pointer::fun2(:)
|||            real*4 input2
|||         end function fun2
|||      end interface
|
|||      real*4 a,b
|||      real*4, pointer::fun2_output(:)
|
|||      a = 0
|
|||      if(input1.eq.0) then
|||         fun2_output => fun2(a)
|||         b = fun2_output(0)
|||      end if
|
|||      return
||| end
|
||| I got:
|
||| test.obj : error LNK2001: unresolved external symbol _fun2
||| Debug/project.dll : fatal error LNK1120: 1 unresolved externals
||| Error executing link.exe.
|
|| For the start, you haven't shown us the C code.
|
| Yes, that would help a lot.
|
|| There are two separate issues, though: linking problem (which would
|| be simple to solve) and the incompatibility problem (which requires
|| a bit more).
|
|| As for the linking problem: you're apparently using CVF or IVF.
|| I can't tell what exactly happened, but here are some tips:
|
|| 1) Ensure that the C function is
||    a) marked with extern "C" in the code
|
| extern "C" is used when compiling C code with a C++ compiler,
| usually when mixed with C++ code.  Otherwise, is the C function
| named _fun2, as the message indicates?
<snip>

I took for granted that the C compiler in question is MS VC++
(the most popular choice in conjunction with CVF); for files
with .cpp extension, it assumes C++ name decoration (and I'm not
sure about files with .c extension). Without C++ name decoration,
its linkage alias (decoration) consists of only underscore-prefix
(assuming __cdecl calling convention), case-sensitive of course.
Thus, "extern "C" float* fun(...)" will get decorated as "_fun"
in the .obj file.

But yes, a lot of my reply was based on (educated) guesswork.
Seeing the C code would definitively help.

--
 Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.



Sun, 23 Aug 2009 18:55:34 GMT  
 Calling a dll c function returning a pointer
Hi guys,
I can't thank you enough for you help!
realy, you are great!
About the problem, I took your advice and I redesign it.
Now I'm passing an array (output(3)) to the c function, the c function
assign to this array and after the calling I'm accessing the array in
the fortran and retrieving the information.
Thanks again,
Ohad

Jugoslav Dujic ???:

Quote:


> |
> || (snip)
> ||| But, when I changed the C function so it's returning a pointer to
> ||| float instead of a float:
> |||
> ||| subroutine fun1(input1)
> |||      interface
> |||         function fun2(input2)
> ||| !dec$ attributes  c,dllimport,alias:'_fun2' :: fun2
> |||            real*4, pointer::fun2(:)
> |||            real*4 input2
> |||         end function fun2
> |||      end interface
> |
> |||      real*4 a,b
> |||      real*4, pointer::fun2_output(:)
> |
> |||      a = 0
> |
> |||      if(input1.eq.0) then
> |||         fun2_output => fun2(a)
> |||         b = fun2_output(0)
> |||      end if
> |
> |||      return
> ||| end
> |
> ||| I got:
> |
> ||| test.obj : error LNK2001: unresolved external symbol _fun2
> ||| Debug/project.dll : fatal error LNK1120: 1 unresolved externals
> ||| Error executing link.exe.
> |
> || For the start, you haven't shown us the C code.
> |
> | Yes, that would help a lot.
> |
> || There are two separate issues, though: linking problem (which would
> || be simple to solve) and the incompatibility problem (which requires
> || a bit more).
> |
> || As for the linking problem: you're apparently using CVF or IVF.
> || I can't tell what exactly happened, but here are some tips:
> |
> || 1) Ensure that the C function is
> ||    a) marked with extern "C" in the code
> |
> | extern "C" is used when compiling C code with a C++ compiler,
> | usually when mixed with C++ code.  Otherwise, is the C function
> | named _fun2, as the message indicates?
> <snip>

> I took for granted that the C compiler in question is MS VC++
> (the most popular choice in conjunction with CVF); for files
> with .cpp extension, it assumes C++ name decoration (and I'm not
> sure about files with .c extension). Without C++ name decoration,
> its linkage alias (decoration) consists of only underscore-prefix
> (assuming __cdecl calling convention), case-sensitive of course.
> Thus, "extern "C" float* fun(...)" will get decorated as "_fun"
> in the .obj file.

> But yes, a lot of my reply was based on (educated) guesswork.
> Seeing the C code would definitively help.

> --
>  Jugoslav
> ___________
> www.xeffort.com

> Please reply to the newsgroup.
> You can find my real e-mail on my home page above.



Tue, 25 Aug 2009 00:03:48 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Call Library Function returning a pointer to doubles

2. Calling dll functions which need pointers to be passed as an argument

3. call function from dll with return void*

4. Call function from DLL with return type void*

5. Returning Pointer To Pointer From Function

6. returning base class pointer from function

7. F90 problem compiling function returning pointer array

8. NT & C function returning pointer

9. HELP F90, External function returning pointer

10. functions returning (pointer to) subroutine?

11. VC++ calling fortran function and fortran function calling a c++ function

12. returning ARRAY structures from DLL-functions in Dyalog

 

 
Powered by phpBB® Forum Software