如何解决从 C# 程序的多个位置访问指向 fortran 向量的指针
我正在使用一个 C# 程序来调用 fortran DLL。下面的示例显示了一些工作 C# 代码,该代码声明了一个 double 类型的指针(“ptr_spf”),将其初始化为 null,然后将其传递到填充它的 fortran(在这种情况下,ptr_spf 指向一个双精度向量) .然后我就可以遍历双精度的 fortran 向量并将每个条目添加到 C# 列表中。到目前为止一切顺利。
不幸的是,随着我继续开发代码,我意识到到目前为止我所做的还不够。相反,我需要从 C# 代码中的其他地方(不同的类)访问 ptr_spf 的内容。也就是说,我不想访问包含在 SPFLowValues
列表中的静态存储值,而是想使用 ptr_spf 指向的更新值,因为它们是由对 fortran DLL 的其他调用更新的。我的问题是:如何在类的顶部声明 ptr_spf 并使其对 C# 程序中的其他类公开可用?当我试图将 ptr_spf 的声明移到类的顶部,并用 public unsafe double* ptr_spf;
定义它时,Visual Studio 不喜欢它在我使用它时未初始化的事实(请参阅屏幕截图这篇文章的结尾)。最重要的是,有没有办法使指向 fortran 双精度向量的指针公开可用,以便我可以从 C# 程序的其他部分访问它?
C#:
class cshare_call2fortran {
// declaration of some variables
public static List<double> SPFlowValues = new List<double>();
...
// declare comms with fortran DLL
...
[DllImport("libmf6d.dll",CallingConvention = CallingConvention.StdCall)]
public unsafe static extern int get_value_ptr_double([In] byte[] address,[In,Out] ref double* ptr);
...
// varIoUs functions
...
// question pertains to the following function
public static void get_spflow_ptr()
{
int index_spf = individual_varnames.Findindex(x => x.Contains("INFLOW"));
var SPFlow_Address = Encoding.ASCII.GetBytes(individual_varnames[index_spf] + char.MinValue);
int rank_spf = 0;
result = get_var_rank(SPFlow_Address,ref rank_spf);
var shape_spf = new int[rank_spf];
result = get_var_shape(SPFlow_Address,shape_spf);
unsafe
{
double* ptr_spf = null;
result = get_value_ptr_double(SPFlow_Address,ref ptr_spf);
for (int i = 0; i < shape_spf[0]; ++i)
{
SPFlowValues.Add(ptr_spf[i]);
spflow_len++;
}
}
}
}
Fortran 函数(包含在有助于查看“get_value_ptr_double”中的内容的情况下):
function get_value_ptr_double(c_var_address,c_arr_ptr) result(bmi_status) bind(C,name="get_value_ptr_double")
!DEC$ ATTRIBUTES DLLEXPORT :: get_value_ptr_double
character (kind=c_char),intent(in) :: c_var_address(*) !< memory address string of the variable
type(c_ptr),intent(inout) :: c_arr_ptr !< pointer to the array
integer(kind=c_int) :: bmi_status !< BMI status code
! local
character(len=LENMEMPATH) :: mem_path
character(len=LENVARNAME) :: var_name
integer(I4B) :: access_type
logical(LGP) :: found
real(DP),pointer :: scalar_ptr
real(DP),dimension(:),pointer,contiguous :: array_ptr
real(DP),dimension(:,:),contiguous :: array2D_ptr
integer(I4B) :: rank
bmi_status = BMI_FAILURE
call split_address(c_var_address,mem_path,var_name)
rank = -1
call get_mem_rank(var_name,rank)
if (rank == 0) then
call mem_setptr(scalar_ptr,var_name,mem_path)
c_arr_ptr = c_loc(scalar_ptr)
else if (rank == 1) then
call mem_setptr(array_ptr,mem_path)
c_arr_ptr = c_loc(array_ptr)
else if (rank == 2) then
call mem_setptr(array2D_ptr,mem_path)
c_arr_ptr = c_loc(array2D_ptr)
else
write(istdout,*) 'BMI Error: unsupported rank for variable '//var_name
return
end if
bmi_status = BMI_SUCCESS
end function get_value_ptr_double
以下是一个屏幕截图,显示了尝试将 ptr_spf 的声明移动到类的开头时的错误:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。