Я хочу вызвать подпрограмму FORTRAN из C #, используя команды, введенные на консоли.Я пытался в течение двух дней, читал много веб-страниц и следовал многим советам, но безуспешно.
Вот типичный пример моих многочисленных неудачных попыток.
Используя текстовый редактор (Блокнот), я создаю этот файл с именем "fdll.f90"
module fdll
implicit none
contains
subroutine testFDLL(char)
character(12) :: char
write(6,*)" Hello FORTRAN : let us do something ...",char
return
end
end module
На консоли MS-DOS (CMD.EXE) я набираю следующую команду инажмите «Enter»:
C:\Compilers\fortran\mingw32\bin\gfortran.exe -shared -o fdll.dll fdll.f90
Появятся два новых файла с именами «fdll.dll» и «fdll.mod».
Используя текстовый редактор Monodevelop C #, я создаю следующий C #Исходный файл с именем «DLLImport.cs»
using System;
using System.Runtime.InteropServices;
public static class DLLImport
{
public static void Main(string[] args)
{
RunFortranDLL ();
}
public static void RunFortranDLL()
{
FortranLib.testFDLL("Please work!");
}
}
public static class FortranLib
{
private const string dllName = "fdll.dll";
[DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void testFDLL(string Plea);
}
В консоли я ввожу следующую команду:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:go.exe DLLImport.cs
Появляется новый файл с именем «go.exe».Я набираю «идти».
В результате появляется всплывающее окно с сообщением «go.exe перестал работать».Это дает мне возможность закрыть программу.На консоли MS-DOS появилось следующее сообщение:
Unhandled Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at Fortran.Lib.testFDLL(String Plea)
at DLLImport.Main(String[] args)
Что я сделал не так?Как я могу заставить это работать?
Я использую 64-битный ноутбук SONY под управлением Windows 8.1.Я использую последнюю версию gfortran (i686-w64-mingw32).
ОБНОВЛЕНИЕ: я изменил исходный код FORTRAN для разрешения ISO_C_BINDING (следуя совету Пьера).Новая версия:
module fdll
contains
subroutine testFDLL(char) bind(C)
USE ISO_C_BINDING
character (C_CHAR) :: char(20)
write(6,*)" Hello FORTRAN : let us do something ..."
return
end subroutine
end module
Я также изменил исходный код C #, чтобы он отправлял символьную строку в FORTRAN в виде массива (как описано здесь: http://www.luckingtechnotes.com/calling-fortran-dll-from-csharp/). Новый код C #:
using System;
using System.Runtime.InteropServices;
public static class DLLImport
{
public static void Main(string[] args)
{
RunFortranDLL ();
}
public static void RunFortranDLL()
{
FortranLib.testFDLL(ToCharacterArrayFortran("Please work!",20));
}
public static char[] ToCharacterArrayFortran(this string source, int length)
{
var chars = new char[length];
int sourceLength = source.Length;
for (int i = 0; i < length; i++)
{
if (i < sourceLength)
chars[i] = source[i];
else
chars[i] = ' '; // Important that these are blank for Fortran compatibility.
}
return chars;
}
}
public static class FortranLib
{
private const string dllName = "fdll.dll";
[DllImport(dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void testFDLL(char[] Plea);
}
Я не вносил изменений в аргументы командной строки, запускающие компиляторы, ни компиляция, ни gfortan, ни csc не жаловались на какие-либо из этих изменений.введите «go»), появляется то же сообщение об ошибке.
Может кто-нибудь объяснить, что не так, или нет, с тем, что я сделал. Неужели так сложно заставить C # отправить строку символов в подпрограмму FORTRAN?