Такой же подход можно использовать. Что лучше всего зависит от того, что, по вашему мнению, является лучшим способом для ваших клиентов C взаимодействовать с вашими объектами Fortran. Некоторые мысли должны быть помещены в это, прежде чем писать слишком много кода.
Как показано, существование y
компонента является деталью, что код C, вероятно, не нужно заботиться о - вместо вызова процедуры sety_a
вы могли бы просто назвать его set_a
.
Если в компоненте типа COMPLEXF
будет много операций, и вы хотите избежать уровня косвенности или если таких компонентов COMPLEXF
, то вы можете использовать адрес C подобъекта, который соответствует этому компоненту как непрозрачный дескриптор.
Ради примера, изменить GetHandle
и ReleaseHandle
процедур в linked answer для работы с COMPLEXF
типа, как тип верхнего уровня (то есть - заменить COMPLEXF
для всех выступлений SIMPLEF
в этом ответе). Затем можно написать QueryYHandle
процедуру или аналогичный, вдоль линий:
FUNCTION QueryYHandle(handle) RESULT(y_handle)
TYPE(C_PTR), INTENT(IN), VALUE :: handle
TYPE(C_PTR) :: y_handle
TYPE(COMPLEXF), POINTER :: p
!***
CALL C_F_POINTER(handle, p)
y_handle = C_LOC(p%y)
END FUNCTION QueryYHandle
Теперь вы можете работать с ручкой на SIMPLEF
подобъекте непосредственно - с помощью точно такой же запрос */Set * процедуры, как в связанном ответ ,
Там нет необходимости писать процедуры для освобождения объекта, выдвинутого y_handle
в этом случае, поскольку срок службы субобъекта, связанный с y
компонентом определяется время жизни объекта, который имеет тот субобъект - это субобъект воля уходят, когда вызывается ReleaseHandle для супер-объекта COMPLEXF
.
Обратите внимание на то, что в подходе, как указано выше, не существует защиты для неправильного обращения дескриптора между языками (например, если код C случайно вызвал процедуру, предназначенную для работы с дескриптором COMPLEXF
с который фактически был для объекта SIMPLEF
). Если это проблематично, тогда защита может быть добавлена, возможно, путем связывания типа дескриптора с адресом C в объекте, используемом как непрозрачный дескриптор, и проверки этого типа дескриптора, прежде чем пытаться связать указатель Fortran с объектом, назначенным адресом C.
Спасибо за подробный ответ. Поэтому в Fortran я все еще могу изменить компонент y SIMPLEF переменной COMPLEXF, а затем C вернет обновленный компонент с помощью компоновки C_LOC. Я предполагаю, что если бы я хотел, я мог бы еще получить доступ к подкомпонентам y на стороне C на этом этапе, или я мог бы просто приравнять y (уже полученный с C_LOC) к другой переменной типа SIMPLEF с обновленными значениями в C. – Stam