在C#中导入FORTRAN DLL不会对DLL内的数据进行操作

时间:2015-10-27 13:32:32

标签: c# .net dll import fortran

将FORTRAN中的DLL导入C#时遇到问题。基本上FORTRAN DLL是处理数据的变量和访问器函数的数据库。我想使用这些导出的函数来设置和获取DLL中的数据。

这是FORTRAN DLL包含的内容:

 ! Database
 include "test.f90"
 !DEC$ ATTRIBUTES DLLEXPORT :: /DBASE/  

 subroutine DBASE_GET_ADDRESS(iAddress, nBytes, Bytes)
 !DEC$ ATTRIBUTES ALIAS:'DBASE_MODULE_mp_DBASE_GET_ADDRESS' :: DBASE_GET_ADDRESS
 !DEC$ ATTRIBUTES DLLEXPORT :: DBASE_GET_ADDRESS

 subroutine DBASE_SET_ADDRESS(iAddress, nBytes, Bytes)
 !DEC$ ATTRIBUTES ALIAS:'DBASE_MODULE_mp_DBASE_SET_ADDRESS' :: DBASE_SET_ADDRESS
 !DEC$ ATTRIBUTES DLLEXPORT :: DBASE_SET_ADDRESS

数据库包含在“test.f90”中并导出,因此其他非托管代码可以直接访问它。通常它的目标是作为共享内存。

2个子程序正在访问“test.f90”中的数据。我没有粘贴整个身体,因为它是关于SO的格式化噩梦,但它们按预期工作。

现在我最初的想法是我可以在C#中导入这些函数,并从那里对数据库变量(也是DLL的一部分)进行操作。这就是我所做的:

    [DllImport("Test_Dbase.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void DBASE_MODULE_mp_DBASE_GET_ADDRESS(ref Int32 iAddress, ref Int16 nBytes, ref Byte Bytes);

    [DllImport("Test_Dbase.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void DBASE_MODULE_mp_DBASE_SET_ADDRESS(ref Int32 iAddress, ref Int16 nBytes, ref Byte Bytes);

然后我写了一些包装函数,所以我可以传入一个带有值的变量名来方便访问。这似乎可以正常使用我在本地解决方案中添加的DLL,我可以成功设置和检索数据。

当我将C#可执行文件与其他进程一起使用时,会出现问题 关于这个共享DLL的工作。我的可执行文件似乎在它的本地副本上运行,并且在其他进程中没有看到任何变化。

Top: C# process Bottom: Fortran process

我对托管代码和非托管代码之间的Interop很新,所以很可能我的方法存在严重缺陷。任何输入将不胜感激。如果需要,我可以提供更多代码或信息。

谢谢,

德拉戈什

1 个答案:

答案 0 :(得分:0)

您必须动态加载dll。

public delegate void FortnarInterface(ref Int32 iAddress, ref Int16 nBytes, ref Byte Bytes);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);

IntPtr dllHandle = LoadLibrary("Test_Dbase.dll");
IntPtr functionHandle = Kernel32.GetProcAddress(dllHandle, "DBASE_MODULE_mp_DBASE_GET_ADDRESS");

FortnarInterface function =(FortnarInterface)Marshal.GetDelegateForFunctionPointer(functionHandle, typeof(FortnarInterface));

//call your fortran function
function(your arguments here)

Kernel32.FreeLibrary(dllHandle);