Hi, I had a similar problem
once concerning using external files from C and proposed a solution in the mail
below; maybe it is of use for you. TRNSYS 17 should introduce a new FILE
keyword to solve this problem more properly.
--- 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:
Recently, I implemented
another method to use ‘real’ external files with TYPES written in
C/C++. It is way bizarre, but works:
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 :
Mark.Goldsworthy@csiro.au [mailto:Mark.Goldsworthy@csiro.au] Hi, I have read some posts on passing file names or labels to
C++ TRNSYS types but I don't think this question has been definitively
answered. This is what I have done: In the TRNSYS.h file I have the following lines which map
the fortran functions to C: extern "C" __declspec(dllimport) char*
_cdecl TRNSYSFUNCTIONS_mp_GETLUFILENAME(int* LU); Then
in the type I have: char *ss, *ss2; This code works (doesn't crash) but prints to the log file: "Label not available" "Cannot find a file associated with that
logical unit" I did link the file, logical unit and labels correctly
in the proforma so that is not the problem. Does anyone know what I am doing wrong? Thanks, Mark |