HELP: passing structure from VBA to Fortran DLL
Author |
Message |
Johnny Y Boe #1 / 8
|
 HELP: passing structure from VBA to Fortran DLL
I'm clueless as to what I did wrong. Below is just a simplified example to test what's going on. I have no problem passing structures that contain strings and long (*4), or strings and double (Real *8), but strings and long *AND* double just won't work. In that case, VBA passes the strings and long variables no problem, but the double variable gets passed as some number way small, close to zero. It then gets manipulated as intended in the fortran DLL and passed back. Please look at the below VBA declaration and call, and the Fortran structure. Any pointer would be appreciated. ************VBA module******************* ' user-defined data type Public Type Section tube_material As String lTube_Material As Long 'length of character string; must be calculated in function Arrangement As String lArrangement As Long 'length of character string; must be calculated in function Num_Tubes As Long Rows As Long Debug As Long Max_HT As Double End Type
(strucin As Section, strucout As Section) Function Eshell1_1(tube_mat, arr, tubenum, numrows, ibug, maxq) As Variant On Error Resume Next ' Local variables Dim arrayout(6) As Variant Dim strucin As Section Dim strucout As Section 'set string variables strucin.tube_material = tube_mat strucin.Arrangement = arr ' determine lengths of string variables after they are set strucin.lTube_Material = Len(strucin.tube_material) strucin.lArrangement = Len(strucin.Arrangement) strucin.Num_Tubes = tubenum strucin.Rows = numrows strucin.Debug = ibug strucin.Max_HT = maxq Call structry(strucin, strucout) arrayout(1) = strucout.tube_material arrayout(2) = strucout.Arrangement arrayout(3) = strucout.Num_Tubes arrayout(4) = strucout.Rows arrayout(5) = strucout.Debug arrayout(6) = strucout.Max_HT Eshell1_1 = arrayout End Function ******************Fortran structure*************** Structure /Section/ Character *8 Tube Material, Arrangement Interger *4 Num_Tubes, Rows, Debug Real *8 Max_HT End Structure
|
Wed, 26 Dec 2001 03:00:00 GMT |
|
 |
Jeff Ashle #2 / 8
|
 HELP: passing structure from VBA to Fortran DLL
This is an observation, probably not a solution: I know that VB adds 'invisible' fillers to UDTs to start member variables on certain boundaries; if, for instance, you define a UDT as one integer followed by one long and another as 2 integers and one long, a variable of either type will return a lenB of 8, and the longs will both occupy bytes 5-8. It seems to make sense that your problem is not what variable types you are declaring but where each side is interpreting boundaries between variables to be. Does it work better if you declare 2 longs on the fortran side (one being essentially a dummy), to correct the alignment? Quote:
> I'm clueless as to what I did wrong. Below is just a simplified example > to test what's going on. > I have no problem passing structures that contain strings and long (*4), > or strings and double (Real *8), but strings and long *AND* double just > won't work. In that case, VBA passes the strings and long variables no > problem, but the double variable gets passed as some number way small, > close to zero. It then gets manipulated as intended in the Fortran DLL > and passed back. > Please look at the below VBA declaration and call, and the Fortran > structure. Any pointer would be appreciated. > ************VBA module******************* > ' user-defined data type > Public Type Section > tube_material As String > lTube_Material As Long 'length of character string; must be > calculated in function > Arrangement As String > lArrangement As Long 'length of character string; must be > calculated in function > Num_Tubes As Long > Rows As Long > Debug As Long > Max_HT As Double > End Type
> (strucin As Section, strucout As Section) > Function Eshell1_1(tube_mat, arr, tubenum, numrows, ibug, maxq) As > Variant > On Error Resume Next > ' Local variables > Dim arrayout(6) As Variant > Dim strucin As Section > Dim strucout As Section > 'set string variables > strucin.tube_material = tube_mat > strucin.Arrangement = arr > ' determine lengths of string variables after they are set > strucin.lTube_Material = Len(strucin.tube_material) > strucin.lArrangement = Len(strucin.Arrangement) > strucin.Num_Tubes = tubenum > strucin.Rows = numrows > strucin.Debug = ibug > strucin.Max_HT = maxq > Call structry(strucin, strucout) > arrayout(1) = strucout.tube_material > arrayout(2) = strucout.Arrangement > arrayout(3) = strucout.Num_Tubes > arrayout(4) = strucout.Rows > arrayout(5) = strucout.Debug > arrayout(6) = strucout.Max_HT > Eshell1_1 = arrayout > End Function > ******************Fortran structure*************** > Structure /Section/ > Character *8 Tube Material, Arrangement > Interger *4 Num_Tubes, Rows, Debug > Real *8 Max_HT > End Structure
|
Wed, 26 Dec 2001 03:00:00 GMT |
|
 |
Klaus H. Probs #3 / 8
|
 HELP: passing structure from VBA to Fortran DLL
I don't know much about the FORTRAN compiler, but you might want to check whatever passes there for struct alignment. VB will align struct members on DWORD (4-bit) boundaries, which might just be throwing off those doubles. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please post/reply to the newsgroup(s) so that everyone can benefit from the discussion. Regards, Klaus H. Probst, MCP
ICQ: 22454937 The VB Box: http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quote: > I'm clueless as to what I did wrong. Below is just a simplified example > to test what's going on. > I have no problem passing structures that contain strings and long (*4), > or strings and double (Real *8), but strings and long *AND* double just > won't work. In that case, VBA passes the strings and long variables no > problem, but the double variable gets passed as some number way small, > close to zero. It then gets manipulated as intended in the Fortran DLL > and passed back. > Please look at the below VBA declaration and call, and the Fortran > structure. Any pointer would be appreciated. > ************VBA module******************* > ' user-defined data type > Public Type Section > tube_material As String > lTube_Material As Long 'length of character string; must be > calculated in function > Arrangement As String > lArrangement As Long 'length of character string; must be > calculated in function > Num_Tubes As Long > Rows As Long > Debug As Long > Max_HT As Double > End Type
> (strucin As Section, strucout As Section) > Function Eshell1_1(tube_mat, arr, tubenum, numrows, ibug, maxq) As > Variant > On Error Resume Next > ' Local variables > Dim arrayout(6) As Variant > Dim strucin As Section > Dim strucout As Section > 'set string variables > strucin.tube_material = tube_mat > strucin.Arrangement = arr > ' determine lengths of string variables after they are set > strucin.lTube_Material = Len(strucin.tube_material) > strucin.lArrangement = Len(strucin.Arrangement) > strucin.Num_Tubes = tubenum > strucin.Rows = numrows > strucin.Debug = ibug > strucin.Max_HT = maxq > Call structry(strucin, strucout) > arrayout(1) = strucout.tube_material > arrayout(2) = strucout.Arrangement > arrayout(3) = strucout.Num_Tubes > arrayout(4) = strucout.Rows > arrayout(5) = strucout.Debug > arrayout(6) = strucout.Max_HT > Eshell1_1 = arrayout > End Function > ******************Fortran structure*************** > Structure /Section/ > Character *8 Tube Material, Arrangement > Interger *4 Num_Tubes, Rows, Debug > Real *8 Max_HT > End Structure
|
Thu, 27 Dec 2001 03:00:00 GMT |
|
 |
Howard Henry Schlunde #4 / 8
|
 HELP: passing structure from VBA to Fortran DLL
Quote: > I don't know much about the FORTRAN compiler, but you might want to check > whatever passes there for struct alignment. VB will align struct members on > DWORD (4-bit) boundaries, which might just be throwing off those doubles.
Actually, it puts it on 4 Byte boundaries, not 4 bit. -- Howard Henry 'Gawyn Ballpeen' Schlunder Gawyn Developments; Core developer http://venus.ajusd.org/~hschlund/
|
Thu, 27 Dec 2001 03:00:00 GMT |
|
 |
Anthony Jone #5 / 8
|
 HELP: passing structure from VBA to Fortran DLL
Quote: >******************Fortran structure*************** > Structure /Section/ > Character *8 Tube Material, Arrangement > Interger *4 Num_Tubes, Rows, Debug > Real *8 Max_HT > End Structure
Ok so here's what might seem a dumb question but what does this structure look like in memory.? In order for it to match the VB type def you posted the two Character*8 elements would have to be composed of a two long word descriptor. The first long word would be a pointer to the first character of the string and the second long word would be it's length (although why that would be needed I don't know). I suspect that in fact the fixed length strings are actually allocated as part of the structure just as is the case with fixed length strings in VB type defs. Hence you could try using fixed length strings in the VB type def and lose the length fields. However, I'm not sure how VB will handle (if at all) any unicode-to-ansi conversion that may be necessary. You might therefore have to resort to fixed length byte array's instead of strings in the type def. -- Anthony Jones Secta Group Ltd
|
Thu, 27 Dec 2001 03:00:00 GMT |
|
 |
Marco A. Garci #6 / 8
|
 HELP: passing structure from VBA to Fortran DLL
Johnny, There are quite a few problems in what you are trying to do. I don't have time to get into many of the details, but here are a few clues that may help you. 1) About your VB structure: Public Type Section tube_material As String lTube_Material As Long Arrangement As String lArrangement As Long Num_Tubes As Long Rows As Long Debug As Long Max_HT As Double End Type tube_material and Arrangements are BStrings, so what the structure has is a pointer to the string (4 bytes), not the string itself. You may be able to solve this problem using fixed length strings, but I have not tried this. VB will align structures the same way FORTRAN does. Provided you take the necessary precautions in FORTRAN, alignment should not a problem. 2) Your Fortran structure: Structure /Section/ Character *8 Tube Material, Arrangement Interger *4 Num_Tubes, Rows, Debug Real *8 Max_HT End Structure You are missing several fields here (lTube_Material and lArrangement). Character*8 won't make it as alignment can change between fields, but not inside a field. To ensure alignment, FORTRAN compilers are free to re-arrange the order of the structure's field, unless you explicitly use the SEQUENTIAL modifier. Your FORTRAN structure should look like this: type Section SEQUENTIAL integer *4 PtrTube_Material integer *4 ITube Material integer*4 PtrArrangement integer*4 IArrangement Interger*4 Num_Tubes integer*4 Rows integer*4 Debug Real *8 Max_HT End type PtrTube_Material and PtrArrangement are pointers to null terminated strings, you need to convert these into acceptable FORTRAN strings. Also, I do not recommend that you change the values of these strings in your Fortran subroutine, unless you know how to handle BStrings at the API level (or unless you use a tool as f90VB's Bstrings library) Best regards, -- Marco A. Garcia Canaima Software 1632 Dale Street San Diego, CA 92102 Telephone: (619) 233-6831
http://www.CanaimaSoft.com Developers of f90SQL, the complete database connectivity solution for Fortran, and f90VB the tools to interface VB/VBA and Fortran
Quote: > I'm clueless as to what I did wrong. Below is just a simplified example > to test what's going on. > I have no problem passing structures that contain strings and long (*4), > or strings and double (Real *8), but strings and long *AND* double just > won't work. In that case, VBA passes the strings and long variables no > problem, but the double variable gets passed as some number way small, > close to zero. It then gets manipulated as intended in the Fortran DLL > and passed back. > Please look at the below VBA declaration and call, and the Fortran > structure. Any pointer would be appreciated. > ************VBA module******************* > ' user-defined data type > Public Type Section > tube_material As String > lTube_Material As Long 'length of character string; must be > calculated in function > Arrangement As String > lArrangement As Long 'length of character string; must be > calculated in function > Num_Tubes As Long > Rows As Long > Debug As Long > Max_HT As Double > End Type
> (strucin As Section, strucout As Section) > Function Eshell1_1(tube_mat, arr, tubenum, numrows, ibug, maxq) As > Variant > On Error Resume Next > ' Local variables > Dim arrayout(6) As Variant > Dim strucin As Section > Dim strucout As Section > 'set string variables > strucin.tube_material = tube_mat > strucin.Arrangement = arr > ' determine lengths of string variables after they are set > strucin.lTube_Material = Len(strucin.tube_material) > strucin.lArrangement = Len(strucin.Arrangement) > strucin.Num_Tubes = tubenum > strucin.Rows = numrows > strucin.Debug = ibug > strucin.Max_HT = maxq > Call structry(strucin, strucout) > arrayout(1) = strucout.tube_material > arrayout(2) = strucout.Arrangement > arrayout(3) = strucout.Num_Tubes > arrayout(4) = strucout.Rows > arrayout(5) = strucout.Debug > arrayout(6) = strucout.Max_HT > Eshell1_1 = arrayout > End Function > ******************Fortran structure*************** > Structure /Section/ > Character *8 Tube Material, Arrangement > Interger *4 Num_Tubes, Rows, Debug > Real *8 Max_HT > End Structure
|
Fri, 28 Dec 2001 03:00:00 GMT |
|
 |
#7 / 8
|
 HELP: passing structure from VBA to Fortran DLL
|
Fri, 19 Jun 1992 00:00:00 GMT |
|
 |
Johnny Y Boe #8 / 8
|
 HELP: passing structure from VBA to Fortran DLL
Quote:
> It seems to make sense that your problem is not what variable types you are > declaring but where each side is interpreting boundaries between variables > to be. Does it work better if you declare 2 longs on the fortran side (one > being essentially a dummy), to correct the alignment?
The dummy does it. I - declared the vb UDT strings as "String * 8" and got rid of the pointers. - added a Single dummy before the Double (no need for dummies for subsequent Doubles) Thank you all for the tips. Quote:
> > I'm clueless as to what I did wrong. Below is just a simplified example > > to test what's going on. > > I have no problem passing structures that contain strings and long (*4), > > or strings and double (Real *8), but strings and long *AND* double just > > won't work. In that case, VBA passes the strings and long variables no > > problem, but the double variable gets passed as some number way small, > > close to zero. It then gets manipulated as intended in the Fortran DLL > > and passed back. > > Please look at the below VBA declaration and call, and the Fortran > > structure. Any pointer would be appreciated. > > ************VBA module******************* > > ' user-defined data type > > Public Type Section > > tube_material As String > > lTube_Material As Long 'length of character string; must be > > calculated in function > > Arrangement As String > > lArrangement As Long 'length of character string; must be > > calculated in function > > Num_Tubes As Long > > Rows As Long > > Debug As Long > > Max_HT As Double > > End Type
> > (strucin As Section, strucout As Section) > > Function Eshell1_1(tube_mat, arr, tubenum, numrows, ibug, maxq) As > > Variant > > On Error Resume Next > > ' Local variables > > Dim arrayout(6) As Variant > > Dim strucin As Section > > Dim strucout As Section > > 'set string variables > > strucin.tube_material = tube_mat > > strucin.Arrangement = arr > > ' determine lengths of string variables after they are set > > strucin.lTube_Material = Len(strucin.tube_material) > > strucin.lArrangement = Len(strucin.Arrangement) > > strucin.Num_Tubes = tubenum > > strucin.Rows = numrows > > strucin.Debug = ibug > > strucin.Max_HT = maxq > > Call structry(strucin, strucout) > > arrayout(1) = strucout.tube_material > > arrayout(2) = strucout.Arrangement > > arrayout(3) = strucout.Num_Tubes > > arrayout(4) = strucout.Rows > > arrayout(5) = strucout.Debug > > arrayout(6) = strucout.Max_HT > > Eshell1_1 = arrayout > > End Function > > ******************Fortran structure*************** > > Structure /Section/ > > Character *8 Tube Material, Arrangement > > Interger *4 Num_Tubes, Rows, Debug > > Real *8 Max_HT > > End Structure
|
Sat, 29 Dec 2001 03:00:00 GMT |
|
|
|