在Windows GetProcAddress中使用OpenMP和"英特尔Visual Fortran&quo



我正在通过Microsoft Visual Studio 2015 IDE使用"英特尔Fortran编译器15.0"。我正在学习OpenMP(最终(并行运行我的代码部分。我的代码需要从.dlls加载子例程。我有下面的程序,它用HelloWorld子例程加载.dll并调用该子例程;下面的代码在一个简单的控制台应用程序中执行得很好。

program LoadThisLibrary

Use DFWIN
Use DFLIB
implicit none
!Variable declarations
Character (len=8) SubName
!Pointer declarations
Integer i !not used but must be declared as part of a POINTER declaration.
Pointer (p,i)
Integer(INT_PTR_KIND()) paa(100)  !declares an integer array that will contain pointer addresses

!Declare an interface for MySub                                            
Interface
Subroutine MySub
End Subroutine MySub
End Interface

! Declare a pointer/pointee structure - this allows us to later "call" a pointer by its pointee (subroutine) name. 
! This is a CVF function, not "pure fortran"  
Pointer(SubNum,MySub) 

!Load the dll that contains the subroutine we want to run
p = LoadLibrary("HelloDLL.dll"C) 

!Name the subroutine we wish to call from that dll
SubName = TRIM("HELLOSUB")//CHAR(0)
!Get a pointer to the subroutine we want and store it in the pointer array
paa(1) = GetProcAddress(p,SubName)
!set a POINTER to the subroutine's memory location
SubNum = paa(1) 
!Call the subroutine loaded from the dll
Call MySub
end

这是";HelloDLL.dll";

subroutine HelloSub
! Expose subroutine HelloSub to users of this DLL
!
!DEC$ATTRIBUTES DLLEXPORT :: HelloSub
! Variables
character variable

! Body of HelloSub 
print *, "Congratulations! You have run a dll subroutine. You are the best. I am in awe of your brilliance. You have triumphed in the face of adversity. "
READ(*,*) variable
end subroutine HelloSub

为了启用OpenMP指令,我转到Project->控制台属性(在我的IDE中(,然后是Fortran->语言,并设置";处理OpenMP指令";至";生成并行代码(/Qopenmp(";。当我这样做时,而不是其他,不更改我的源代码,我的代码就不再运行。具体来说,我发现LoadLibrary仍然为HelloDLL.dll找到一个地址,但GetProcAddress调用返回一个null值(0(。在主程序代码中是否包含USE OMP_LB或使用任何OpenMP指令或函数似乎无关紧要。我尝试过重命名paa((数组,甚至将地址保存为一个普通整数——似乎什么都不起作用。

如果有任何建议或见解,我将不胜感激。显然,启用OpenMP不仅仅是允许访问OpenMP的功能,我只是不明白为什么它会对GetProcAddress产生任何影响。如果可以的话,请帮忙!非常感谢。

空终止的子例程名称(8+1=9(比SubName变量的长度(8(长。当赋值给SubName的表达式中存在null终止符时,它将作为赋值的一部分被截断(不能将九个字符放入八个字符中(。

空终止符是否恰好紧跟在SubName的存储之后取决于内存中变量的布局(以及可能的随机机会(。如果没有null终止符,传递给GetProcAddress的名称将毫无意义。/Qopenmp将改变内存中变量的布局。

更正SubName的长度。考虑使用一个可分配的字符标量,使您的代码对以后过程名称长度的更改具有鲁棒性。

(风格或可移植性的其他问题也存在,但它们更主观。(

最新更新