Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

173
Views
¿Cómo se pasa el tipo complejo de Fortran a C#?

Supongamos que tengo el siguiente código Fortran

 subroutine COMPLEX_PASSING(r, i, c) !DEC$ ATTRIBUTES DLLEXPORT::COMPLEX_PASSING REAL*8 :: r, i COMPLEX*8 :: c c = cmplx((r * 2), (i * 2)) return end

El código Fortran fue compilado con

 gfortran -c complex_passing.f90 gfortran -fPIC -shared -o complex_passing.dll complex_passing.o

¿Cómo llamaría a esta subrutina en C#? He probado el siguiente código:

 using System; using System.Runtime.InteropServices; namespace FortranCalling { class Program { static void main(string[] args) { double real = 4; double imaginary = 10; COMPLEX c = new COMPLEX(); complex_passing( ref real, ref imaginary, ref c); Console.WriteLine("Real: {0}\nImaginary: {1}", c.real, c.imaginary); Console.ReadLine(); } [StructLayout(LayoutKind.Sequential)] struct COMPLEX { public double real; public double imaginary; } [DllImport("complex_passing.dll", EntryPoint = "complex_passing_", CallingConvention = CallingConvention.Cdecl)] static extern void complex_passing(ref double r, ref double i, ref COMPLEX c); } }

Con poco éxito, mi estructura COMPLEX parece estar devolviendo datos basura:

 Real: 134217760.5 Imaginary: 0

Cuando esperaría que la parte real fuera 8 y la parte imaginaria fuera 20.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

gfortran trata el COMPLEX*8 no estándar como un complejo de 8 bytes de tamaño, con componentes reales e imaginarios de 4 bytes cada uno. En su lugar, necesita un complejo de 16 bytes, con componentes reales e imaginarios de 8 bytes cada uno ( COMPLEX*16 ) o debe cambiar el lado de C# en consecuencia.

El efecto de esto es visible con lo siguiente bajo gfortran:

 complex*8 :: c8 = (8d0, 20d0) complex*16 :: c16 = 0 c16%re = TRANSFER(c8,c16) print*, c8, c16 end

Por supuesto, no debería usar complex* en absoluto. La falta de coincidencia del argumento se puede ver usando complex(kind=..) .

Considere la siguiente fuente "Fortran":

 subroutine s(r, i, c) real(kind(0d0)) :: r, i complex(kind(0e0)) :: c c = cmplx((r*2),(i*2)) end subroutine s interface ! Interface block required to lie to some versions of gfortran subroutine s(r, i, c) real(kind(0d0)) :: r, i complex(kind(0d0)) :: c end subroutine s end interface complex(kind(0d0)) c call s(4d0, 10d0, c) print*, c%re end

y compararlo con la fuente de Fortran:

 subroutine s(r, i, c) real(kind(0d0)) :: r, i complex(kind(0d0)) :: c c = cmplx((r*2),(i*2)) end subroutine s complex(kind(0d0)) c call s(4d0, 10d0, c) print*, c%re end

Además, en lugar de usar kind(0d0) , etc., existen varias constantes de interoperabilidad de C y constantes de tamaño de almacenamiento de iso_fortran_env .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!