[英]Passing string from Fortran dll to C#
我正在嘗試動態加載Fortran DLL並將字符串從fortran傳遞回C#。 在fortran代碼中,一切看起來都很好,但是當返回C#時,字符串的值會丟失。 相反,在C#中設置的初始值又回來了。 我試圖使用'ref'關鍵字來獲取通過引用傳遞的字符串,但后來我得到如下錯誤。 我究竟做錯了什么?
運行時遇到了致命錯誤。 錯誤的地址是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);
}
}
}
備查。 我添加了[In,Out],一切正常。
[DllImport(_dllName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void GetString([In, Out] char[] str);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.