Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

DLL Argument List Order

mattsdad
Beginner
1,172 Views

I get different results for the debug and release versions of a call to a DLL subroutine with a missmatched argument list. We are using a DLL plugin that we set up to "attach" multiple times with different internal data sturctures. We accidentally added the handle to the version subroutine in the first version of the plugin. Since the version routine cannot use the handle argument, we are removing it from the new versions, but we wanted to use the same subroutine name. So, we tested the connection with a missmatched argument list, and we are getting different results with release and debug versions. P.S. we load the DLL to pointers and assign the pointer immediately before each call to allow different plugins to be used as well as differnt internal data structures with the same plugin.

Original:

Subroutine Version(handle, version_structure)

New:

Subrougine Version(version_structure)

  TYPE Version_t
    INTEGER :: Major_Version
    INTEGER :: Minor_Version
    INTEGER :: Build_Number
    INTEGER :: Revision_Number
  END TYPE Version_t

When we load the old plugin with two arguments onto the new kernel with one argument in debug mode we get the correct data out of the version_structure. (Unexpected, but interesting.)

When we load the old plugin with two arguments onto the new kernel with one argument in release mode we get zeros back in the version_structure.

Does the debug code load the arguments differently? Or use the argument name somehow? Why does this work for debug but not for release mode?

0 Kudos
8 Replies
Steven_L_Intel1
Employee
1,172 Views
My guess is that you aren't loading the DLL you think you are. There is nothing special about debug vs. release when it comes to argument order.
0 Kudos
mattsdad
Beginner
1,172 Views
I put a comment into the old routine in the DLL and it is printing at the right place in the output, so I know the routine is being called. The only difference is the return information is different in release and debug for the same code. I believe the other routines are also being call correctly because the simulation produces similar results to prior runs.
0 Kudos
mattsdad
Beginner
1,172 Views
SUBROUTINE Aero_get_plugin_api_version(aero_id, version) INTEGER(KIND=8), INTENT(IN) :: aero_id TYPE(Version_t), INTENT(OUT) :: version !DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'aero_get_plugin_api_version' :: aero_get_plugin_api_version print *, ' ************ in Aero_get_plugin_api_version *************' version = Version_t(1,0,0,286) END SUBROUTINE Aero_get_plugin_api_version
0 Kudos
Steven_L_Intel1
Employee
1,172 Views
I suggest you add more diagnostic output for the release version to see if it is getting the correct arguments passed. Is the call also from Fortran code? I am wondering if you have STDCALL/C calling convention mismatches.
0 Kudos
mattsdad
Beginner
1,172 Views
There are no convention mismatches. We have been using this code successfully for months. The upgrade is just starting and this is the first change, so the only difference is the removal of the unnecessary parameter. We ran the test for the mismatched argument lists just to see if the prior version would crash or what. It didn't crash, but it produced these strange results which we cannot explain. Below are further extracts from the code. I believe you now have the whole text of interest. You will note that the call to the get_api_version routine has had the argument list changed from what was in the older DLL. INTERFACE SUBROUTINE Aero_get_plugin_api_version(version) USE S6D_Parameters, ONLY: Version_t TYPE(Version_t), INTENT(OUT) :: version END SUBROUTINE Aero_get_plugin_api_version END INTERFACE POINTER(p_aero_get_plugin_api_version, Aero_get_plugin_api_version) !$OMP THREADPRIVATE(p_aero_get_plugin_api_version) aero_plugin%handle = LoadLibrary (TRIM(dll_name)//ACHAR(0)) aero_plugin%aero_get_plugin_api_version_ptr = & GetProcAddress(aero_plugin%handle, 'aero_get_plugin_api_version'C) IF (aero_plugin%aero_get_plugin_api_version_ptr == 0) THEN CALL messenger(‘Failed to attach routine Aero_get_plugin_api_version') success = .FALSE. RETURN END IF . . . aero_plugin%is_attached = .TRUE. IF (aero_plugin%is_attached) THEN p_aero_get_plugin_api_version = aero_plugin%aero_get_plugin_api_version_ptr CALL Aero_get_plugin_api_version(version) ! CALL Aero_get_plugin_api_version(aero_plugin%id, version) END IF CALL create_version_string(plugin_l%plugin_version, version_string) CALL messenger(LOG_VERBOSE, 'Successfully Loaded Plug-in: ' // & TRIM(plugin_l%plugin_name) // ' ' // TRIM(version_string)) SUBROUTINE create_version_string(version, version_string) IMPLICIT NONE TYPE(Version_t), INTENT(IN) :: version CHARACTER(LEN=*), INTENT(OUT) :: version_string CHARACTER(LEN=6) :: Major, Minor, Rev WRITE (Major, "(I5)") version%Major_Version WRITE (Minor, "(I5)") version%Minor_Version WRITE (Rev, "(I5)") version%Revision_Number version_string = 'version ' // TRIM(ADJUSTL(Major)) // '.' // & TRIM(ADJUSTL(Minor)) // ' rev ' // TRIM(ADJUSTL(Rev)) END SUBROUTINE create_version_string
0 Kudos
mattsdad
Beginner
1,172 Views
When I call the debug version of the DLL from the release version of the kernel I get the wrong data back. When I call the release version of the DLL from the debug kernel I get the right data. In other words, the debug kernel gets the right data regardless of the DLL compilation configuration. The release kernel always gets the wrong data.
0 Kudos
mattsdad
Beginner
1,172 Views
Let me just add: This is not a significant issue for us. We can proceed without any code changes. This is more of a compiler issue that Intel should look into. I do not absolutely need an answer, but I am particularly curious. I know I only provided patches from the code, so if anything else critical is missing, please let me know. If you find an answer, please let me know.
0 Kudos
Steven_L_Intel1
Employee
1,172 Views
We can't look into it unless you provide us with a test case that demonstrates the problem. I'm not going to try to construct one from the extracts because that almost always does not reflect your actual code and situation.
0 Kudos
Reply