Desired use case
We use ROSCO as a controller DLL inside OrcaFlex, a marine dynamics simulation package. OrcaFlex is a Windows GUI application that loads DISCON via an embedded Python wrapper using ctypes. We've been using ROSCO this way for several years.
Description
The 64-bit conda-forge build of ROSCO 2.10.3 causes the host GUI process to terminate silently on the first DISCON call (iStatus=0). The same simulation works fine via the OrcaFlex API (which is a console process), and a build from source using MSYS2 MinGW also works fine in the GUI.
We believe the issue is the unconditional write (*,*) banner in ReadSetParameters.f90 (line 206), which writes to stdout on the first call regardless of LoggingLevel. In a GUI process there's no console, so the C runtime's stdout file descriptor is invalid. What happens next depends on which C runtime the DLL is linked against:
- msvcrt (e.g. MSYS2 MinGW builds, previous NREL releases): the write silently fails and execution continues
- UCRT (e.g. conda-forge builds): the invalid file descriptor triggers UCRT's default invalid parameter handler, which terminates the process immediately with no error message
We think this hasn't surfaced before because earlier pre-built DLLs were linked against msvcrt. The conda-forge toolchain uses UCRT, which is stricter about this.
There are a number of other print * / write (*,*) calls elsewhere in the codebase that could cause the same problem under different conditions. It would be really helpful if stdout writes could be avoided in the DLL — ROSCO already has good mechanisms for output via the log file and the aviFAIL/avcMSG return parameters.
Steps to reproduce issue
- Load a 64-bit conda-forge build of ROSCO 2.10.3 into any Windows GUI application (no console attached)
- Call DISCON with iStatus=0
- The host process terminates immediately with no error message
Current behavior
The host process is silently terminated during the first DISCON call due to UCRT's invalid parameter handler being triggered by a write to an invalid stdout file descriptor.
Expected behavior
DISCON should not write to stdout/stderr, as a DLL cannot assume the host process has valid standard streams. Diagnostic output could be routed through the existing log file and aviFAIL/avcMSG mechanisms instead.
Code versions
- ROSCO 2.10.3
- Windows 11 64-bit
- DLL from conda-forge (linked against ucrtbase.dll)
- Host application: OrcaFlex (Delphi GUI), calling DISCON via embedded Python/ctypes
Workaround
We've confirmed that suppressing UCRT's invalid parameter handler around the DISCON call resolves the issue. Building from source with MSYS2 MinGW (which links against msvcrt) also avoids it.
Desired use case
We use ROSCO as a controller DLL inside OrcaFlex, a marine dynamics simulation package. OrcaFlex is a Windows GUI application that loads DISCON via an embedded Python wrapper using ctypes. We've been using ROSCO this way for several years.
Description
The 64-bit conda-forge build of ROSCO 2.10.3 causes the host GUI process to terminate silently on the first DISCON call (iStatus=0). The same simulation works fine via the OrcaFlex API (which is a console process), and a build from source using MSYS2 MinGW also works fine in the GUI.
We believe the issue is the unconditional
write (*,*)banner inReadSetParameters.f90(line 206), which writes to stdout on the first call regardless ofLoggingLevel. In a GUI process there's no console, so the C runtime's stdout file descriptor is invalid. What happens next depends on which C runtime the DLL is linked against:We think this hasn't surfaced before because earlier pre-built DLLs were linked against msvcrt. The conda-forge toolchain uses UCRT, which is stricter about this.
There are a number of other
print */write (*,*)calls elsewhere in the codebase that could cause the same problem under different conditions. It would be really helpful if stdout writes could be avoided in the DLL — ROSCO already has good mechanisms for output via the log file and theaviFAIL/avcMSGreturn parameters.Steps to reproduce issue
Current behavior
The host process is silently terminated during the first DISCON call due to UCRT's invalid parameter handler being triggered by a write to an invalid stdout file descriptor.
Expected behavior
DISCON should not write to stdout/stderr, as a DLL cannot assume the host process has valid standard streams. Diagnostic output could be routed through the existing log file and
aviFAIL/avcMSGmechanisms instead.Code versions
Workaround
We've confirmed that suppressing UCRT's invalid parameter handler around the DISCON call resolves the issue. Building from source with MSYS2 MinGW (which links against msvcrt) also avoids it.