[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [TRNSYS-users] Error in cpp programming



Dear alone,

 

Reading TRNSYS external files from C or C++ is somewhat tricky.

 

The problem comes from the fact that

a)       the TRNSYS kernel (not the TYPE) will open the external file at the beginning of the simulation and (assign file handles)

b)       file handles are not interoperable between compilers (sometimes not even between the release and debug version of the same FORTRAN compiler)

 

To work around the problem, it has been proposed to use the special cards mechanism instead:

  1. specify the file name as a special card
  2. read it and open() the file in the initialization of the C code
  3. close() it in the type at simulation stop

 

Recently, I implemented another method to use ‘real’ external files with TYPES written in C/C++. It is way bizarre, but works:

  1. A DLL, FileReader.dll, is implemented in FORTRAN; this Dll provides functions to read the next character for a given external file
  2. The C type implements a function to read the next line in a given external file based on 1. and uses the external file like a traditional type in FORTRAN would.

 

I provided the FileReader.DLLs for those who do not have a FORTRAN compiler and the C++ code implementing a class to access it follows (made with Compaq Visual FORTRAN for compatibility with the official TRNSYS 16.1 release):

ftp://ftp.cstb.fr/software/Trnsys/FileReader/

 

 

With this, you can just read the file in C++ like this:

 

                  double LUN;

                  LUN=par[0];

 

                  iunit=info[0];

                  itype=info[1];

 

 

                std::string code;

                TrnsysFileReader theReader;

 

                while (!theReader.Eof())

                  {

                        string tmp = theReader.ReadNextLine((int) LUN);

                        code.append(rtrim(tmp));

                        code.append("\r\n");

                  }

 

 

Hope this helps,

 

Werner

#include <cmath>

#include <fstream>

 

//#include "windows.h"

#include "TrnsysFileReader.h"        

 

typedef int (__cdecl* LPFNDLLFUNC1)(int*);

LPFNDLLFUNC1 lpfnDllFunc1;

 

TrnsysFileReader::TrnsysFileReader()

{

        lpfProcFunction = NULL;

       

        TCHAR path[1024];

        GetModuleFileName(NULL, path, sizeof(path));

 

            std::string str = path;

 

            unsigned tmp1, tmp2;

            tmp1 = tmp2 = 0;

 

            for(unsigned i = 0; i < str.length(); i++)

            {

                  if(path[i] == '\\')

                  {

                        tmp2 = tmp1;

                        tmp1 = i;

                  }

            }

 

            str.resize(tmp2);

             

            #ifdef _DEBUG

                  str.append("\\Userlib\\DebugDLLs\\FileReader.dll");

            #else

                  str.append("\\Userlib\\ReleaseDLLs\\FileReader.dll");

            #endif

 

            hLibrary = LoadLibrary(str.c_str());

       

        eof = false;

        maxFileWidth=1000; // from TrnsysConstants.f90

      }

 

TrnsysFileReader::~TrnsysFileReader()

      {

          FreeLibrary(hLibrary);

      }

 

      bool TrnsysFileReader::Eof()

      {

        return eof;

      }

 

      int TrnsysFileReader::ReadNextChar(int LUN)

      {

        int c;

 

        if (hLibrary == NULL) return -1;

        lpfnDllFunc1 = (LPFNDLLFUNC1) GetProcAddress( hLibrary,

                        "READNEXTCHAR");

        int ilun = (int) LUN;

        c = lpfnDllFunc1(&ilun);

            if(c == -2) throw std::bad_exception("Problème avec le fichier");

        if (c == -1) eof = true;

        return c;

 

      }

 

      std::string TrnsysFileReader::ReadFile(int LUN)

      {

        std::string result;

        char c;

        while ((c = ReadNextChar(LUN)) && (!eof))

        {         

          std::string s;

          s.append(&c,1);

          result.append(s);

        }

 

        return result;

      }

 

      std::string TrnsysFileReader::ReadNextLine(int LUN)

      {

        std::string result;

        char c;

        while ((c = ReadNextChar(LUN)) && (!eof) && (result.length() < (unsigned int)maxFileWidth-1))

        {         

          std::string s;

          s.append(&c,1);

          result.append(s);

        }

 

        return result;

      }

 

 

 

 

 

 

TrnsysFileReader.h :

 

#ifndef trnsyfilereaderincluded

#define trnsyfilereaderincluded

 

#include <cmath>

#include <fstream>

#include "windows.h"

#include <string.h>

#include "TRNSYS.h" //TRNSYS acess functions (allow to acess TIME etc.)

 

typedef int (__cdecl* LPFNDLLFUNC1)(int*);

 

class TrnsysFileReader

{

 

private :

      HMODULE hLibrary;

      FARPROC lpfProcFunction;  

      bool eof;

      LPFNDLLFUNC1 lpfnDllFunc1;

      int maxFileWidth;

 

public:

      TrnsysFileReader();

      ~TrnsysFileReader();

      bool Eof();

      int ReadNextChar(int LUN);

      std::string ReadNextLine(int LUN);

      std::string ReadFile(int LUN);

};

 

 

 

#endif

 


De : rgaray@labein.es [mailto:rgaray@labein.es]
Envoyé : mercredi 29 juillet 2009 17:38
À : LISTA DE CORREO USUARIOS TRN
SYS
Objet : [TRNSYS-users] Error in cpp programming

 


Dear All,

I´m programming a new type in cpp and It gives an error I do not get to understand. I get an error in the fgets.c function. This function is an ordinary cpp function for reading an external file.
I have previously debugged the code itself with a dummy application that called the dll and worked fine, but when I try to debug the dll with trnsys it crashes.

Has anyone previously had this problem?

I´m quite lost so any help will be appreciated. Thank You.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Imprime sólo lo imprescindible, recuerda tu compromiso con el MEDIO AMBIENTE // Behar beharrezkoa baino ez imprimatu, gogoratu zure INGURUGIROArekiko konpromezua // Before printing think about the ENVIRONMENT

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Este mensaje se dirige exclusivamente a su destinatario y puede contener información privilegiada o confidencial. Si no es vd. el destinatario indicado,
queda notificado de que la utilización, divulgación y/o copia sin autorización está prohibida en virtud de la legislación vigente.
Si ha recibido este mensaje por error, le rogamos que nos lo comunique inmediatamente por esta misma vía y proceda a su destrucción.

Mezu honek eta erantsita dituen agiriek (baldin baditu) isilpeko informazioa izan dezakete. Hori dela eta, hutsegite baten ondorioz jasotzen duenak
jakin beza bertan dagoen informazioa ezkutukoa dela eta legeak galarazi egiten duela berori baimenik gabe erabiltzea.

This message is intended exclusively for its addressee and may contain information that is confidential and protected by professional privilege.
If you are not the intended recipient you are hereby notified that any dissemination, copy or disclosure of this communication is strictly prohibited by law.
If this message has been received in error, please immediately notify us via e-mail and delete it.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------