Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

176
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda