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

Problem passing arguments to a DLL for 32bits but working in 64bits

alexandre_c_1
Beginner
1,384 Views

I am writing intel fortran code  that is going to be compile into two dll, one will be called from excel 32 bits VBA code and the other from excel 64 bits VBA code.

I do not have problems calling and running the dll in 64 bits but I have problem in 32bits. In 32 bits, I have add the sequence statement in my type statement (see below). I am also using the Stdcall convention and the sequence type = Yes(/align:sequence)

I did a write statement of the arguments at entry in the dll and I figure that I am getting 0 starting with the first real*8 variable. Real*8 variables are declared as double in VBA

I am using the type statement for my arguments, which does not seems to be cover in the forums.

Does anybody have a hint for solving this problem ?

here is part of my code for the main subroutine of the dll

SUBROUTINE PS(arg)

      IMPLICIT NONE

      !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "PS" ::PS
      !DEC$ ATTRIBUTES STDCALL :: PS
      !DEC$ ATTRIBUTES REFERENCE::arg    

      type s_data
        SEQUENCE
        integer     sGroup
        integer     sBIRTH
        real*8      sPEN
        ....

      end type

      type(s_data) arg

 

 

 

  

 

 

 

0 Kudos
13 Replies
Steven_L_Intel1
Employee
1,384 Views

What, exactly, is the problem? You haven't shown anything yet that is different between the 32-bit and 64-bit environments, at least as far as Fortran is concerned.

0 Kudos
alexandre_c_1
Beginner
1,384 Views

Argument are passed properly in 64 bits but not in 32 bits

 

0 Kudos
andrew_4619
Honored Contributor III
1,384 Views

!DEC$ ATTRIBUTES DLLEXPORT, decorate, ALIAS : "PS" ::PS

Maybe? X64 has no symbol decoration  for stdcall but in x32 it is _name@nn

0 Kudos
Steven_L_Intel1
Employee
1,384 Views

Again, what goes wrong? What is "improper"? Can you identify what DOES get passed and where it ends up in the structure? How is your argument defined in VBA? 

I would generally recommend using "TYPE, BIND(C)" rather than a SEQUENCE type nowadays. I don't know what you mean by your remark about TYPE "not covered in the forums".

0 Kudos
alexandre_c_1
Beginner
1,384 Views

I mean user defined type !

here is how the user type is defined in VBA :

!Here is the different declaration

Public Declare PtrSafe Sub PS011 Lib "C:\....\PS.dll" Alias "PS" (PSData As PSType)

Type PSType
    Group     As Long  
    BIRtH     As Long  
    PEN    As Double
    .....

End Type

Public PSData11 As PSType

!In one a the subroutine I have the call

 Call PS011(PSdata11)

from the PEN variable and on I have 0 that are passed and some funny numbers.

Group and Birth get passed properly

Thank you

0 Kudos
alexandre_c_1
Beginner
1,384 Views

I have change the

Structure Member Alignment  from default to 4bytes(/align:rec4bytes)

For 64 it is now set to default and

for 32 bits it is set to 4bytes(/align:rec4bytes)

and its seems to solve part of my problem.
I now have a problem starting with the variable that are defined as single in VBA or real in Fortan in my user-defined type.

Does that give you any hint ?

0 Kudos
Steven_L_Intel1
Employee
1,384 Views

I would not expect that to make a difference. But I would recommend instead that you use:

Type, BIND(C) :: PsType

and remove SEQUENCE.

This will give you better control over alignment inside derived types.

VBA single is the same as Fortran REAL. If you would like more help, you will need to provide more details than "I now have a problem".

0 Kudos
alexandre_c_1
Beginner
1,384 Views

It seems like it is the same problem I had with the real*8(double) but it is now on the real(single) variable.

It is returning funny numbers starting with the real(single) variable on entry within the dll

You mean that I have to use the Bind(C) in VBA ?

0 Kudos
Steven_L_Intel1
Employee
1,384 Views

Sorry, I missed that your Type declaration was VBA. Sorry. What I meant was to replace your Fortran declaration of the type sdata to start with TYPE, BIND(C) :: sdata and to remove SEQUENCE.

Perhaps VBA is padding the values. What I would do is, on entry to the Fortran routine, print out each of the structure values in hexadecimal and try to determine what it ought to look like and see what VBA is passing. Since you're calling this from VBA you may have to write the data to a file, as there is no console. Or I would run the whole thing in the debugger and examine the memory for the argument to see what it looks like.

0 Kudos
alexandre_c_1
Beginner
1,384 Views

Finally the 4bytes(/align:rec4bytes) on its own (without the sequence type = Yes(/align:sequence) and without the "sequence" in the Type statement) seems to solve the problem but it is creating a warning message (for warning #6379: The structure contains one or more misaligned fields.)

Should I worry about this ?

0 Kudos
Steven_L_Intel1
Employee
1,384 Views

The warning alerts you to reduced performance - it probably doesn't matter in your case. If you can, rearrange the members of the type so that all the doubles are first, followed by all the singles or integers. I'm not a fan of using compile switches to paper over coding or design issues.

0 Kudos
alexandre_c_1
Beginner
1,384 Views

Your suggestion is interesting but I cannot afford doing it since I do not have control over an old VB6 interface that will also be using the dll.

Thank you again.

 

0 Kudos
Steven_L_Intel1
Employee
1,384 Views

In that case, don't worry about the misalignment.

0 Kudos
Reply