1
我想動態加載一個Fortran dll並將字符串從fortran傳回C#。在fortran代碼中一切看起來都很好,但是當返回到C#時,字符串的值將丟失。相反,在C#中設置的初始值返回。我試圖使用'ref'關鍵字來獲取通過引用傳遞的字符串,但隨後出現如下所示的錯誤。我究竟做錯了什麼?從Fortran dll傳遞字符串到C#
運行時遇到致命錯誤。錯誤的地址是0x709ce248,線程0x2ac4。錯誤代碼是0xc0000005。此錯誤可能是CLR中的錯誤,也可能是用戶代碼中不安全或不可驗證的部分。此錯誤的常見來源包括COM-interop或PInvoke的用戶編組錯誤,這可能會破壞堆棧。
Fortran代碼:
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#代碼:
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);
}
}
}
如果直接''[DllImport(「FortLib.dll」)]'是否可以工作? – ja72
是的,它的工作原理。問題是我需要動態加載它。 – JesperW
呃,其實。它的工作原理是因爲我可以添加[進出]。如果我離開它,我會得到與動態調用中相同的行爲。 – JesperW