- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have previously had succes with asking questions about an fortran to c interface, so here goes another one.
I am trying to call a function in a C compiled library file (this is obtained from third party)called hasp_login that will take as input two integers and a string and return an integer stating if login successeeded or not (along with a handle).
The C header file looks like this:
typedef hasp_u32_t hasp_handle_t;
typedef hasp_u32_t hasp_feature_t;
typedef void *hasp_vendor_code_t;
hasp_status_t HASP_CALLCONV hasp_login(hasp_feature_t feature_id,
hasp_vendor_code_t vendor_code,
hasp_handle_t *handle);
Now thefeature_id looks like this inc
#define HASP_DEFAULT_FID 0
#define HASP_PROGNUM_OPT_CLASSIC 0x00001000
#define HASP_FEATURETYPE_MASK 0xffff0000
#define HASP_PROGNUM_DEFAULT_FID (HASP_DEFAULT_FID | HASP_PROGNUM_FEATURETYPE)
const hasp_feature_t feature = HASP_PROGNUM_DEFAULT_FID | HASP_PROGNUM_OPT_CLASSIC;
and the vendor_code something likeunsigned char vendor_code[] =
"IHTKDNCKDKDK"
"DKDKJTKDKDLS"
"KDOSKJ((/1212J"
"KKDI";
finaly the handle is of type hasp_handle_t and the call to make in C is
status = hasp_login(feature,(hasp_vendor_code_t *)vendor_code,&handle);
This all works fine, however I would like to do this from fortran, so I have made:
integer, parameter :: HASP_DEFAULT_FID = z'00000000'
integer, parameter :: HASP_PROGNUM_FEATURETYPE = z'ffff0000'
integer, parameter :: HASP_PROGNUM_OPT_CLASSIC = z'00001000'
integer, parameter :: HASP_PROGNUM_DEFAULT_FID = IOR(HASP_PROGNUM_FEATURETYPE,IOR(HASP_DEFAULT_FID,HASP_PROGNUM_OPT_CLASSIC))
interface hasp_login
function hasp_login(feature_id, vendor_code, handle)
!DEC$ ATTRIBUTES REFERENCE, ALIAS:'_hasp_login@12' :: hasp_login
!DEC$ ATTRIBUTES VALUE :: feature_id
!DEC$ ATTRIBUTES REFERENCE :: vendor_code
!DEC$ ATTRIBUTES VALUE :: handle
integer*4 :: feature_id
integer*4 :: vendor_code
integer*4 :: handle
end function
end interface
!character*41 :: vendor_codecharacter, dimension(41) :: vendor_code
vendor_code"IHTKDNCKDKDK" // &
"DKDKJTKDKDLS" // &
"KDOSKJ((/1212J" // &
"KKDI"C
and the call
status = hasp_login(HASP_PROGNUM_DEFAULT_FID, loc(vendor_code), handle)
where handle is an integer.
However this does not work i.e. the C libraryshould have contacted my license manager and performed a login.
Any suggestions?
Regards
Lars
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. Run the pure C version and record the function argument types and values just before and after entry to hasp_login, using a debugger or by inserting printf() statements.
2. Write a dummy replacement for hasp_login with the same interface, link it with the Fortran caller, and run using a debugger. If the observed types and values do not match those recorded in Step 1, fix the code.
3. Replace the dummy routine with the actual routine. Test.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On the Fortran side, you have not defined the type of Function Hasp_Login. It might be best to write a C-wrapper function for Hasp_Login that actually uses integer references that can be called from Fortran.
The use of a string argument complicates things. If the memory allocation for the string buffer is made on the C-side, I would tend to send the buffer address AND the buffer length (including terminating null character) to the Fortran so that it can write your required login text into it (but not overrun the buffer!).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In C/Fortran mixed programming, it is important to understand which argument should be declared reference and which should be value.
In C, your call is
status = hasp_login(feature,(hasp_vendor_code_t *)vendor_code,&handle);
So it indicates that you pass the address of the variable "handle".
So in fortran, I think that you should declare handle as REFERENCE and not VALUE. I suppose that this function returns a value in handle so it must be passed by reference.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4:
This sounds as a good idea and I will look into this.
anthonyrichards:
Just to clarify whatI mean by "it does not work". My fortran program compiles, links and builds fine, however during execution it does not succeed in performing a login at my licens manager. Since my program written in C (just used for testing, this is not to be used in my fortran program) can call the c-library just fine and did make a login at my license manager I think that it is my fortran interface that is wrong i.e. I am not sending the correct values/references to C. I know when ever I write something like "it does not work", I always end up leaving out some important info - so hopefully this made it more clear.
You are correct that I did not define the type of the function Hasp_Login. I tried this i.e. the function is now defined as an integer. This hadthe effectthat Inow am able to read the returned error message (which states that the vendor_code is invalid i.e. my text string is not recieved by the c libraryas intended).
Your last point aboutmemory allocation on the c-side will force me to writing a c-wrapper(or am I missing the point)? I have thought aboutthat, but beeing quite the novice in C, Iwas hopingI could just fixtheinterface in fortran.
gvautier:
I think you are right. I have changed theinterface and now declares the handle as REFERENCE.
So after implementing the changes (definition of the type Hasp_Login and declaring the handle by REFERENCE), I am left with a returned error code during executionstating that my vendor_code is invalid.
I am troubled by the definition of the type hasp_vendor_code_t:
typedef void *hasp_vendor_code_t;
Would this need special attention in my interface (why is the type defined as void)?
Again thanks for all the input.
Regards
Lars
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suggest you change the declaration of vendor_code to have the VALUE attribute.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Comming from fortran I have always found the concept of "level of indirection" tricky - I think I will need to read up on this.
Thank you very much
-Lars
![](/skins/images/48A1642489FEF8D34D940AC6791CBDC2/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page