LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

gfortran

Solved!
Go to solution

Iエラーについて教えてください。

gfortranを用いて作成した .dll をlabviewで使いたいのです.

コードを以下に示します。

-------------------------------------------------

Test code of Fortran90:

 ! Fortran Code: myfortrancode.f90

subroutine multiply_array(input, output, size)

real, intent(in) :: input(:)

real, intent(out) :: output(:)

integer, intent(in) :: size

integer :: i

! (input* 2 process)

do i = 1, size

output(i) = input(i) * 2.0

end do

end subroutine multiply_array

------------------------------------------------------------

gfortranで以下のコマンドを実施

[Gfortran part:]

1: making object file

gfortran -c myfortrancode.f90 -o myfortrancode.o

2: making .dll file

gfortran -shared -o myfortrancode.dll myfortrancode.o

 

labviewでdllを配置 (添付資料)

[LabVIEW 設定項目] --------------------------------------------

Using the .dll in LabVIEW

  Using    : “ Function Palette/ Call Library Function Node “

  Set       : “myfortrancode.dll ”

:  [input and output]

    Name :input

    Type : Array

    Data type: 8-byte-Double

                Dimension ;1

                Array Format : Array Data Pointer

                Minimum Size : <None>.

 

                [ size]

                 Name  : Size :

   Type : Numeric

   Data type: Singled 8-bit-Integer

Pass : <None>

 -----------------------------------------------

LabVEWを走らせると error 1097 and まったく計算していないようです。

処置をご教示ください。

鈴木

 

 

0 Kudos
Message 1 of 18
(1,960 Views)

I want to solve my trouble.

I am using gfortran and wants to use dll in LavVIEW.

Test code of Fortran90:

 

---------------------------------------------

 ! Fortran Code: myfortrancode.f90

subroutine multiply_array(input, output, size)

real, intent(in) :: input(:)

real, intent(out) :: output(:)

integer, intent(in) :: size

integer :: i

! (input* 2 process)

do i = 1, size

output(i) = input(i) * 2.0

end do

end subroutine multiply_array

------------------------------------------------------------

[Gfortran part:]

1: making object file

gfortran -c myfortrancode.f90 -o myfortrancode.o

2: making .dll file

gfortran -shared -o myfortrancode.dll myfortrancode.o

 

[LabVIEW part]

Using the .dll in LabVIEW

  Using    : “ Function Palette/ Call Library Function Node “

  Set       : “myfortrancode.dll ”

:  [input and output]

    Name :input

    Type : Array

    Data type: 8-byte-Double

                Dimension ;1

                Array Format : Array Data Pointer

                Minimum Size : <None>.

 

                [ size]

                 Name  : Size :

   Type : Numeric

   Data type: Singled 8-bit-Integer

Pass : <None>

 

LabVEW returns error 1097 and output does not return correct answer.

 

Please teach me where to fixt

 

0 Kudos
Message 2 of 18
(1,989 Views)

There is no need to create two topics with the same content.

 

You have a few problems here:

 

1) real in Fortran corresponds to Single Precision Float in LabVIEW. To use Double Precision Float you would need to use the double data type in Fortran.

 

2) I'm not really sure what Fortran flavor you are using but GNU Fortran and other Fortran versions I know off have the same parameter passing order as C, meaning parameters are passed from left to right on the stack. This matches the order from top to bottom in the LabVIEW Call Library Node. Your VI has the size parameter as first parameter in the Call Library Node, your Fortran function has it as last parameter.

 

3) Instead of wiring a fixed constant to the size input of the function, use the Array Length of the incoming array! Otherwise if you pass in a shorter array than 5 elements, the DLL function will access invalid memory as it tries to go past the actually passed in array. If you pass in a larger array, it will only process the first 5 elements and ignore the rest.

 

4) Calling external code has some very strict memory management rules. You don't tell LabVIEW to allocate a buffer for the output array. Your Fortran function can't do it as it has no way to pass the according buffer back to the caller and even if it could, you end up with questions like from which memory heap the buffer was allocated and how to tell LabVIEW to use the according free function, which for a Fortran DLL it actually couldn't as it has no knowledge of the according Fortran Runtime library.

 

To avoid these possible ambiguities the only workable solution is that every needed buffer needs to be allocated by the caller, eg. LabVIEW. Since LabVIEW can't know how large this array buffer has to be, you as programmer need to tell it explicitedly.

 

So you need to allocate an array of sufficient length and pass it to the left side of that parameter. There are two ways to do it:

 

- Use of an Initialize Array node with the same number that you passed to the size input.

- Configure in the Call Library Node the "Minimum size" for the output array to be equal to the size parameter.

Rolf Kalbermatter
My Blog
Message 3 of 18
(1,941 Views)

Tanks a lot!!

0 Kudos
Message 4 of 18
(1,886 Views)

I corrected the order of input.

The precision of input and output are set explicitly,ie, real(8).

Again using  next commands

      gfortran -c myfortrancode.f90 -o myfortrancode.o

      gfortran -shared -o myfortrancode.dll myfortrancode.o

 the .dll was made .

Attached vi still makes error.

Will you give me some another suggestion.

0 Kudos
Message 5 of 18
(1,863 Views)

I believe that your line

 

integer, intent(in) :: size

 

will likely mark the size parameter as a by value parameter and then you need to configure it accordingly in the LabVIEW Call Library Node.

 

Also I really very much doubt that integer in Fortran is a 8 bit integer. Most likely it will be a 32-bit integer.

 

However in your earlier code your real parameters were not configured as 8 byte real number, but just simply real.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 18
(1,848 Views)

GNU fortranのdllでlabviewから動かしたいと思っています。

まず

! sample.f90
module sample_module
  implicit none
contains

  subroutine add_numbers(a, b, result)
    real*8, intent(in) :: a, b
    real*8, intent(out) :: result
    result = a + b
  end subroutine add_numbers

end module sample_module

 

で dllを作りlabviewから呼び込むとうまく動きますl

ところがresultのところを配列に作り替え

! sample.f90
module sample_module
  implicit none
contains

  subroutine add_numbers(a, b, result)
    real*8, intent(in) :: a, b
    real*8 , intent(out) :: result(5)
    !real*8  aa
    integer i
   do i=1,5
    result(i) = a + b*2.d0
   end do
  end subroutine add_numbers

end module sample_module

 

でdllを作るとエラー1097で動きません。

原因はどこでしょうか。

なおdllは gfortran 下で」

gfortran -c sample2.f90 -o sample2.o

gfortran -shared -o sample2.dll sample2.f90

で作成してます。

配列の移動がうまくいっていないようです。

よろしくお願いいたします。

 

 

0 Kudos
Message 7 of 18
(1,822 Views)

Memory buffer allocation!

 

Again, you do not specify any array size to allocate in the LabVIEW diagram for the result parameter, but try to write into the according buffer for the first 5 elements of that array. Since you do not specify what array LabVIEW should allocate to pass to the the function, it does not allocate that array, basically it passes a pointer to a zero buffer. Then you try to write into element 0 to 4 of that array and your DLL function grabs into the void as it tries to write into the not allocated buffer.

 

ALWAYS make sure to allocate the correct buffer size in the caller (eg. LabVIEW here) that your function accesses. In this case you have an implicit array size requirement: the caller simply needs to magically know that your function tries to write into 5 elements. Usually it is more prudent to explicitly pass in the size of such buffers from the caller as it of course knows what it allocated AND also use that size parameter in your function to check to not exceed the end of the buffer when reading from or writing to it.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 18
(1,758 Views)
Solution
Accepted by

Thank you for your kind advice!! The main cause of my problem  is byte number of integer,ie, integer * 4. I set the the Data type -Signed  8-bit Integer,pass pointer to Value in  Call Library function,

Thevalue  of fortranfile , integer*4 were set and made  .dll.

Every thing is OK !! Labview returns  acurate value.

Thank you so much.

0 Kudos
Message 9 of 18
(1,742 Views)

Your explanation makes not a lot of sense in relation to your previous post. There is no integer passed at all in that.

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 18
(1,735 Views)