Bonjour,
J'ai des problèmes pour appeler une librarie fortran.
je n'arrive pas à trouver le prototype C# permettant d'appeler la méthode SetData.
J'ai Visual Fortran d'un côté et VS2012 de l'autre.
J'ai fait une appli console c#. j'ai paramétré cette application pour pouvoir exécuter ma DLL fortran en mode debug.

code fortran:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
SUBROUTINE SETDATA(VBARRAY_PTR,NUM_ELEMENT)
        $ ATTRIBUTES DLLEXPORT::SETDATA
	!dec$ ATTRIBUTES ALIAS :'SetData'::SETDATA
 
C	VBARRAY : array of type VB F_LSP_FILE
C	NUM_ELEMENT : NUmber of elements in the array 
	! Definition of the VBARRAY  structure 
 
	use type_Vb
	use dfcom
	use dfnls
 
	implicit none
	Integer NUM_ELEMENT
 
	!  Declare ARRAY_PTR to be a pointer to an integer
	integer dummy
	pointer(VBARRAY_PTR,dummy) 
 
	! Declare a pointer to the head of VB F_LSP_FILE structure
	pointer (F_File_ptr,F_LSP_File_data)
 
	type(F_LSP_File) :: F_LSP_File_Data(NUM_ELEMENT)
 
	character(100) FileName
	character(255) FilePath
	character(100) TypeName
	character(100) FormatName
	character(3) Extention
	integer*2 EngineIndice
 
	include "tlccom.for"
 
	character*255 LOGFILE
 
      COMMON /TAPEWIN/ LOGFILE
 
	integer status
	integer i
	! Use the SafaArray routine to get address of the F_LSP_DATA structure
 
	status=safeArrayAccessData(VBARRAY_PTR,F_File_ptr)
 
	! get info
 
	do i =1,NUM_ELEMENT
 
	! loop for all files
 
		status = MBConvertUnicodeToMB(F_LSP_File_Data(i).FileName,
     +			FileName)
		status= MBConvertUnicodeToMB(F_LSP_File_Data(i).FilePath,
     +		FilePath)
 
		status= MBConvertUnicodeToMB(F_LSP_File_Data(i).TypeName,
     +		TypeName)
 
		status= MBConvertUnicodeToMB(F_LSP_File_Data(i).FormatName,
     +		FormatName)
 
		status= MBConvertUnicodeToMB(F_LSP_File_Data(i).Extention,
     +		Extention)
		EngineIndice=F_LSP_File_Data(i).IndexEngine
 
(...)
Le code fortran fait référence à ce fichier. De ce que j'ai compris, fortran ne permet pas d'inclure des types characterdans une struct, c'est pourquoi le type F_LSP_File a été redéfini dans la méthode SetData, remplaçant les integer*2 par des Character(N).

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
module type_Vb
   ! Use of type F_LSP_File from VB
 
   ! The Visual Basic declaration is:
 
   !Type F_LSP_Files
   ! FileName as String*100
   ! FilePath As String*255
   ! TypeName as String*100
   ! FormatType As String*100
   ! Extention As String*3
   ! IndexEngine as Integer
   !End Type
   !--------------------------------------------------------------------
   implicit none
 
 
   !Type declarations
!dec$ pack : 4
   type F_LSP_File
   ! Strings are passed as Unicode, and so must be defined as arrays
   !  of Integer*2
      sequence
      integer*2      :: FileName(100)
	  integer*2      :: FilePath(255)
	  integer*2      :: TypeName(100)
	  integer*2      :: FormatName(100)
	  integer*2      :: Extention(3)
	  integer*2		 :: IndexEngine
 
   end type F_LSP_File
 
 end module type_vb
Côté C# cela donne ceci:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
        [StructLayout(LayoutKind.Sequential)]
        public struct F_Lsp_File
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string FileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
            public string FilePath;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string TypeName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string FormatName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
            public string Extention;
 
            [MarshalAs(UnmanagedType.I2, SizeConst = 2)]
            public short IndexEngine;
        }
 
[DllImport("LSPTOW.dll", EntryPoint = "SetData", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern void LSP_SetData(
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)]  ref F_Lsp_File[] Fos_Data,
            ref int Num_Elem);
J'ai toujours des problèmes de violation mémoire, ou de type non attendu... je ne sais plus trop quoi tester...

le code fortran suivant:
status=safeArrayAccessData(VBARRAY_PTR,F_File_ptr) inclut surement d'utiliser des types SafeArray. j'ai même essayer les attributs de ce type dans ma signature [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)], sans résultats...

J'ai déja réussi a passer des valeurs dans les variables correspondantes (FilePath, Filename...) il faut bien forcer l'unicode côté c# avec UnmanagedType.BStr sur les variables de la structure, mais tout était désordonné.

Please help