Ich versuche, eine Fortran-DLL dynamisch zu laden und übergeben Sie eine Zeichenfolge zurück von Fortran zu C#. Im Fortran-Code sieht alles gut aus, aber bei der Rückkehr zu C# ist der Wert der Zeichenfolge verloren. Stattdessen ist der Anfangswert, der in C# festgelegt wurde, zurück. Ich habe versucht, das Ref-Schlüsselwort zu verwenden, um die Zeichenfolge zu erhalten, die durch Verweis übergeben wird, aber dann erhalte ich Fehler wie unten. Was mache ich falsch?Zeichenfolge von Fortran dll an C übergeben #
Die Laufzeit hat einen schwerwiegenden Fehler festgestellt. Die Adresse des Fehlers war 0x709ce248 auf Thread 0x2ac4. Der Fehlercode lautet 0xc0000005. Dieser Fehler kann ein Fehler in der CLR oder in den unsicheren oder nicht verifizierbaren Teilen des Benutzercodes sein. Häufige Ursachen für diesen Fehler sind Benutzer-Marshalling-Fehler für COM-Interop oder PInvoke, die den Stack beschädigen können.
Fortran-Code:
module FortLibInterface
implicit none
integer, parameter :: STR_LENGTH = 256
contains
subroutine GetString(Str)
!DIR$ ATTRIBUTES DLLEXPORT::GetString
!DIR$ ATTRIBUTES ALIAS: 'GetString' :: GetString
!DIR$ ATTRIBUTES REFERENCE:: Str
character(len=STR_LENGTH), intent(inout) :: Str
Str = 'bcdef...'
end subroutine
end module
C# -Code:
using System;
using System.Runtime.InteropServices;
namespace FortranCSTest
{
class Program
{
static void Main(string[] args)
{
string dllPath = "C:\\Temp\\FortLib.dll";
FortLibTest lib = new FortLibTest(dllPath);
lib.MakeTestCall();
}
}
public class FortLibTest
{
public const int STR_LENGTH = 256;
public const string FortranFuncName = "GetString";
private string pathToDll = null;
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(String DllName);
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
private static extern bool FreeLibrary(IntPtr hModule);
public FortLibTest(string FullPathToDll)
{
pathToDll = FullPathToDll;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void TypeGetStrInfo(char[] str);
void GetStrInfo(char[] str)
{
IntPtr pDll = LoadLibrary(pathToDll);
if (pDll != IntPtr.Zero)
{
IntPtr pFunc = GetProcAddress(pDll, FortranFuncName);
if (pFunc != IntPtr.Zero)
{
TypeGetStrInfo func = (TypeGetStrInfo)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(TypeGetStrInfo));
func(str);
}
else
{
//Something
}
FreeLibrary(pDll);
}
else
{
//Something
}
}
public void MakeTestCall()
{
char[] str = new char[STR_LENGTH];
str[0] = 'a';
GetStrInfo(str);
}
}
}
Funktioniert es, wenn Sie direkt '[DllImport (" FortLib.dll ")]'? – ja72
Ja, es funktioniert. Das Problem ist, dass ich es dynamisch laden muss. – JesperW
Nun, eigentlich. Es funktioniert, weil ich dann [in, out] hinzufügen kann. Wenn ich das hinterlasse, bekomme ich das gleiche Verhalten wie beim dynamischen Aufruf. – JesperW