02-05-2024 02:03 AM
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 まったく計算していないようです。
処置をご教示ください。
鈴木
Solved! Go to Solution.
02-05-2024 12:27 AM
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
02-05-2024 02:25 AM - edited 02-05-2024 02:30 AM
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.
02-05-2024 05:40 AM
Tanks a lot!!
02-05-2024 07:32 AM
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.
02-05-2024 08:38 AM - edited 02-05-2024 08:40 AM
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.
02-06-2024 07:57 PM
GNU fortranのdllでlabviewから動かしたいと思っています。
まず
で dllを作りlabviewから呼び込むとうまく動きますl
ところがresultのところを配列に作り替え
でdllを作るとエラー1097で動きません。
原因はどこでしょうか。
なおdllは gfortran 下で」
gfortran -c sample2.f90 -o sample2.o
gfortran -shared -o sample2.dll sample2.f90
で作成してます。
配列の移動がうまくいっていないようです。
よろしくお願いいたします。
02-07-2024 04:48 AM
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.
02-07-2024 06:26 AM
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.
02-07-2024 06:43 AM
Your explanation makes not a lot of sense in relation to your previous post. There is no integer passed at all in that.