2010-01-07 2 views
2

Je le FORTRAN suivantLEN_TRIM de FORTRAN se comporte-t-il différemment avec les paramètres transmis?

SUBROUTINE SETPATHS(INPUT) 
    !DEC$ ATTRIBUTES DLLEXPORT::SetPaths 

    CHARACTER*20 INPUT 
    CHARACTER*20 DIRECTORY 

    DIRECTORY = 'ABCDEFG' 

    WRITE(6, *) 'INPUT LEN_TRIM = ', LEN_TRIM(INPUT) 
    WRITE(6, *) 'DIRECTORYLEN_TRIM = ', LEN_TRIM(DIRECTORY) 

    END SUBROUTINE 

Et j'appelle la fonction de C#, en passant 'ABCDEFG'.

Lorsque je définis un point d'arrêt sur mon débogueur, INPUT et DIRECTORY ont exactement les mêmes caractères. Les deux ont 'ABCDEFG' suivi du même nombre d'espaces de fin.

Cependant, les résultats du programme

INPUT LEN_TRIM = 20 
    DIRECTORYLEN_TRIM = 7 

Est-ce un comportement correct? Si les deux chaînes ont les mêmes valeurs, pourquoi LEN_TRIM donne-t-il des résultats différents?

Mise à jour: J'ai trouvé ce problème documenté (bien que ce ne soit pas mon compilateur Intel 8.1). http://support.microsoft.com/kb/89131

+0

complètement irréalisé, mais cela vous dérangerait-il si je vous demande pourquoi vous appelez une fonction dans FORTRAN de C#? –

+1

Le FORTRAN fait le calcul du nombre. C# est ma langue la plus productive pour toute la plomberie. – Larsenal

+0

@Mitch: malheureusement, vous ne pouvez pas battre Lapack. –

Répondre

1

En remplissant explicitement mon C# StringBuilder avec des espaces de fin, le LEN_TRIM s'est comporté comme prévu. This Microsoft KB semble être liée.

Il est étrange, cependant, que dans le débogueur les espaces de fin sont apparus avant même que j'ai fait le remplissage explicite.

+0

Dans votre question précédente, http://stackoverflow.com/questions/2018277/how-to-pass-parameter-from-c-to-fortran-with-parameter-of-type-character50, j'ai expliqué comment fonctionnent les cordes Fortran et a suggéré que vous deviez remplir le reste des chaînes avec des blancs. –

+0

Oui, j'ai lu ça. Cependant, quand je les ai regardés dans le débogueur ils étaient déjà vides sans les remplir explicitement. Ce n'était pas un tas d'ordures. Tous les personnages de 20 ans. – Larsenal

1
[email protected]:~ $ ./a.out 
INPUT LEN_TRIM =   7 
DIRECTORYLEN_TRIM =   7 
[email protected]:~ $ more test.f90 
SUBROUTINE SETPATHS(INPUT) 

CHARACTER*20 INPUT 
CHARACTER*20 DIRECTORY 

DIRECTORY = 'ABCDEFG' 

WRITE(6, *) 'INPUT LEN_TRIM = ', LEN_TRIM(INPUT) 
WRITE(6, *) 'DIRECTORYLEN_TRIM = ', LEN_TRIM(DIRECTORY) 

END SUBROUTINE 
program test 
    character*20 foo 
    foo = "ABCDEFG" 
    call setpaths(foo) 
end program 

Quel compilateur utilisez-vous? ici gfortran.

essayées avec ifort ainsi

$ ifort -v 
Version 8.0 
$ ifort test.f90 
$ ./a.out 
INPUT LEN_TRIM =   7 
DIRECTORYLEN_TRIM =   7 

Je ne sais pas comment l'interface C# peut introduire des problèmes, mais la sémantique de LEN_TRIM sont assez faciles ... si vous dites que les chaînes apparaissent comme égaux le débogage, il y a quelque chose de très louche.

+0

J'utilise le compilateur Intel. – Larsenal

+0

Je ne sais pas si j'ai accès à ifc, je vais essayer de voir ... peut-être ....Quelle version? –

+0

J'utilise la version 8.1. Je me demande si cela a plus à voir avec le fait que j'ai passé dans le StringBuilder de C#. – Larsenal

1

il peut être à la recherche du caractère Terminator, char (0). il peut être différent de \ n caractère

autre possibilité que la longueur de la chaîne n'a pas été passée correctement. La chaîne fortran 77 est passée en deux valeurs, pointeur de chaîne et longueur de chaîne. il n'y a pas de norme sur la façon dont la longueur de la chaîne est passée, la plupart des compilateurs la collent comme un paramètre caché à la fin. pourrait être de 90 fait la même chose pour la compatibilité.

+0

La chaîne Fortran typique utilisée par l'OP est de longueur fixe, rembourrée à l'extrémité avec des flans. La longueur est la longueur déclarée, pas la longueur utilisée. Il n'y a pas de caractère de fin. –

Questions connexes