将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很新,所以很可能我的方法存在严重缺陷。任何输入将不胜感激。如果需要,我可以提供更多代码或信息。
谢谢,
德拉戈什
答案 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);