- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Hello,
In the following code snippet I notice that string lengths are passed to C++ differently:
[fortran]
type MyPro
character(len=256) :: path
end type
subroutine Test
implicit none
type(MyPro):: Pro
character(len=256):: path
integer::err
!these call directly C++ functions defined as
! void dbGet(const char *key, char *pValue, int *err, size_t key_len, size_t value_len)
!
call dbGet("Path", Pro%path, err)
call dbGet("Path", path, err)
end subroutine
[/fortran]
The problem is that on the C++ side value_len gets a 0 value from the first fortran call, but the correct value from the second call.
I would appreciate an explanation for this,
Thanks
Ссылка скопирована
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
We need more details about how you compile and which compiler versions you use, as well as actual source code to demonstrate the problem. Using the attached files and IFort/Icl 13.1.1.171, in the debugger I see 4 and 256 inside DBGET for key_len and value_len during both calls to DBGET.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
This looks like a calling mechanism problem since Fortran doesn't know anything about C++ - it just has a standard way to interface with C. Is your program 32 or 64 bit? As far as I know there is only one calling convention on 64-bit whereas there is a whole plethora of them in 32-bit. I believe the standard is now to have a 1:1 correspondence between Fortran and C argument lists - no more hidden arguments. So with the right calling convention (or in 64-bit) you should be able to do
[fortran]
call dbGet("Path", Pro%path, err, len("Path"), len(Pro%path))
[/fortran]
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
In your case 2 (type embedded), the NULL char you observed after the string is likely accidental.
type MyPro
character(len=256) :: path
integer :: flag
end type
Initialize path as before, but set flag to -1.
Jim Dempsey
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Thanks Jim, I checked with various stack data around the fortran type and it was indeed accidental. This leaves the #2 issue still unsolved.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
I suggest that since your C++ side interface explicitly uses a size argument that you declare the C++ interface on the FORTRAN side with explicit size arguments as sgearg suggests.
Note, you can create a shell function in FORTRAN that is passed (key,value,err) which calls the C++ function with (key,value,err, LEN(key), LEN(value)). Or use LENTRIM in place of LEN.
Jim Dempsey
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Thanks everyone, I finally found a workaround without extra size arguments.since the general issue is to pass any type, array or string. My interface code depends on a custom data mining tool that extracts types from fortran files and their dependent embedded types (if any) and generates binary-compatible C++ structures. It also creates appropriate metadata describing each type, members, descriptors, sizes, etc. These structs have exactly the same size as the fortran types, so I use the metadata to extract the size of anything, including strings. I know, this deviates from my original question, but the issue was more general.

- Подписка на RSS-канал
- Отметить тему как новую
- Отметить тему как прочитанную
- Выполнить отслеживание данной Тема для текущего пользователя
- Закладка
- Подписаться
- Страница в формате печати