CoolProp  6.6.0
An open-source fluid property and humid air property database
CoolPropLib.cpp
Go to the documentation of this file.
1 #if defined(_MSC_VER)
2 # define _CRTDBG_MAP_ALLOC
3 # define _CRT_SECURE_NO_WARNINGS
4 # include <crtdbg.h>
5 #else
6 # include <fenv.h>
7 #endif
8 
9 #include "CoolPropLib.h"
10 #include "CoolProp.h"
11 #include "HumidAirProp.h"
12 #include "DataStructures.h"
13 #include "Exceptions.h"
14 #include "float.h"
16 #include "AbstractState.h"
17 #include "Exceptions.h"
18 #include "Configuration.h"
20 
21 #include <string.h>
22 
23 void str2buf(const std::string& str, char* buf, int n) {
24  if (str.size() < static_cast<unsigned int>(n))
25  strcpy(buf, str.c_str());
26  else
27  throw CoolProp::ValueError("Buffer size is too small");
28 }
29 void HandleException(long* errcode, char* message_buffer, const long buffer_length) {
30  try {
31  throw; // Rethrow the error, and here we handle the error
32  } catch (CoolProp::HandleError& e) {
33  std::string errmsg = std::string("HandleError: ") + e.what();
34  if (errmsg.size() < static_cast<std::size_t>(buffer_length)) {
35  *errcode = 1;
36  strcpy(message_buffer, errmsg.c_str());
37  } else {
38  *errcode = 2;
39  }
40  } catch (CoolProp::CoolPropBaseError& e) {
41  std::string errmsg = std::string("Error: ") + e.what();
42  if (errmsg.size() < static_cast<std::size_t>(buffer_length)) {
43  *errcode = 1;
44  strcpy(message_buffer, errmsg.c_str());
45  } else {
46  *errcode = 2;
47  }
48  } catch (...) {
49  *errcode = 3;
50  }
51 }
52 
53 // In Microsoft Excel, they seem to check the FPU exception bits and error out because of it.
54 // By calling the _clearfp(), we can reset these bits, and not get the error
55 // See also http://stackoverflow.com/questions/11685441/floating-point-error-when-calling-dll-function-from-vba/27336496#27336496
56 // See also http://stackoverflow.com/questions/16849009/in-linux-do-there-exist-functions-similar-to-clearfp-and-statusfp for linux and OSX
58 {
60 #if defined(_MSC_VER)
61  _clearfp(); // For MSVC, clear the floating point error flags
62 #elif defined(FE_ALL_EXCEPT)
63  feclearexcept(FE_ALL_EXCEPT);
64 #endif
65  }
66 };
67 double convert_from_kSI_to_SI(long iInput, double value) {
68  if (get_debug_level() > 8) {
69  std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n", __FILE__, __LINE__, iInput, value).c_str();
70  }
71 
72  switch (iInput) {
73  case CoolProp::iP:
74  case CoolProp::iCpmass:
75  case CoolProp::iCp0mass:
76  case CoolProp::iSmass:
77  case CoolProp::iGmass:
78  case CoolProp::iCvmass:
79  case CoolProp::iHmass:
80  case CoolProp::iUmass:
82  return value * 1000.0;
83  case CoolProp::iDmass:
85  case CoolProp::iQ:
87  case CoolProp::iT:
88  case CoolProp::iPrandtl:
90  return value;
91  default:
92  throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI", iInput).c_str());
93  }
94 }
95 
96 double convert_from_SI_to_kSI(long iInput, double value) {
97  if (get_debug_level() > 8) {
98  std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n", __FILE__, __LINE__, iInput, value).c_str();
99  }
100 
101  switch (iInput) {
102  case CoolProp::iP:
103  case CoolProp::iCpmass:
104  case CoolProp::iCp0mass:
105  case CoolProp::iSmass:
106  case CoolProp::iGmass:
107  case CoolProp::iCvmass:
108  case CoolProp::iHmass:
109  case CoolProp::iUmass:
111  return value / 1000.0;
112  case CoolProp::iDmass:
113  case CoolProp::iQ:
116  case CoolProp::iT:
118  return value;
119  default:
120  throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str());
121  }
122 }
123 
124 EXPORT_CODE long CONVENTION redirect_stdout(const char* file) {
125  FILE* fp = freopen(file, "a+", stdout);
126  return (fp) ? 1 : 0; // 0 = failure if redirection could not be done; original stdout is already closed
127 }
128 EXPORT_CODE int CONVENTION set_reference_stateS(const char* Ref, const char* reference_state) {
129  fpu_reset_guard guard;
130  try {
131  CoolProp::set_reference_stateS(std::string(Ref), std::string(reference_state));
132  return true;
133  } catch (std::exception& e) {
134  CoolProp::set_error_string(e.what());
135  } catch (...) {
136  CoolProp::set_error_string("Undefined error");
137  }
138  return false;
139 }
140 EXPORT_CODE int CONVENTION set_reference_stateD(const char* Ref, double T, double rhomolar, double hmolar0, double smolar0) {
141  fpu_reset_guard guard;
142  try {
143  CoolProp::set_reference_stateD(std::string(Ref), T, rhomolar, hmolar0, smolar0);
144  return true;
145  } catch (std::exception& e) {
146  CoolProp::set_error_string(e.what());
147  } catch (...) {
148  CoolProp::set_error_string("Undefined error");
149  }
150  return false;
151 }
152 
153 // All the function interfaces that point to the single-input Props function
154 EXPORT_CODE double CONVENTION Props1(const char* FluidName, const char* Output) {
155  fpu_reset_guard guard;
156  double val = Props1SI(Output, FluidName);
157  if (!ValidNumber(val))
158  // Error code was already set in Props1SI
159  return val;
160  // val is valid; so, Output is already checked in Props1SI -> get_parameter_index won't throw
162  return convert_from_SI_to_kSI(iOutput, val);
163 }
164 EXPORT_CODE double CONVENTION PropsS(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Ref) {
165  return Props(Output, Name1[0], Prop1, Name2[0], Prop2, Ref);
166 }
167 EXPORT_CODE double CONVENTION Props(const char* Output, const char Name1, double Prop1, const char Name2, double Prop2, const char* Ref) {
168  fpu_reset_guard guard;
169  try {
170  // Get parameter indices
171  std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
173  if (!CoolProp::is_trivial_parameter(iOutput)) {
176 
177  // Convert inputs to SI
178  Prop1 = convert_from_kSI_to_SI(iName1, Prop1);
179  Prop2 = convert_from_kSI_to_SI(iName2, Prop2);
180  }
181 
182  // Call the SI function
183  double val = PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);
184 
185  // Convert back to unit system
186  return convert_from_SI_to_kSI(iOutput, val);
187  } catch (std::exception& e) {
188  CoolProp::set_error_string(e.what());
189  } catch (...) {
190  CoolProp::set_error_string("Undefined error");
191  }
192  return _HUGE;
193 }
194 EXPORT_CODE double CONVENTION saturation_ancillary(const char* fluid_name, const char* output, int Q, const char* input, double value) {
195  fpu_reset_guard guard;
196  try {
197  return CoolProp::saturation_ancillary(fluid_name, std::string(output), Q, std::string(input), value);
198  } catch (std::exception& e) {
199  CoolProp::set_error_string(e.what());
200  } catch (...) {
201  CoolProp::set_error_string("Undefined error");
202  }
203  return _HUGE;
204 }
205 EXPORT_CODE double CONVENTION Props1SI(const char* FluidName, const char* Output) {
206  fpu_reset_guard guard;
207  return CoolProp::Props1SI(std::string(FluidName), std::string(Output));
208 }
209 EXPORT_CODE void CONVENTION Props1SImulti(const char* Outputs, char* backend, const char* FluidNames, const double* fractions,
210  const long length_fractions, double* result, long* resdim1) {
211  fpu_reset_guard guard;
212  try {
213  // Outputs is a delimited string separated by LIST_STRING_DELIMITER
214  std::string delim = CoolProp::get_config_string(LIST_STRING_DELIMITER);
215  // strsplit only support char delimiter
216  if (delim.length() > 1)
217  throw CoolProp::ValueError(format("Length of string delimiter [%d] is bigger than 1 [%d]", delim.length(), delim.size()));
218  std::vector<std::string> _outputs = strsplit(Outputs, delim[0]);
219  // FluidNames is a delimited string separated by LIST_STRING_DELIMITER
220  std::vector<std::string> _fluidNames = strsplit(FluidNames, delim[0]);
221  if (_fluidNames.size() != length_fractions)
222  throw CoolProp::ValueError(
223  format("Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
224  std::vector<double> _fractions(fractions, fractions + length_fractions);
225  std::vector<std::vector<double>> _result = CoolProp::Props1SImulti(_outputs, backend, _fluidNames, _fractions);
226  // if CoolProp::Props1SImulti fails it will return an empty vector -> set result dimensions to 0
227  if (_result.size() == 0) {
228  *resdim1 = 0;
229  } else {
230  if (_result.size() > *resdim1)
231  throw CoolProp::ValueError(format("Result vector [%d] is bigger than allocated memory [%d]", _result[0].size(), *resdim1));
232  *resdim1 = _result[0].size();
233  for (int i = 0; i < _result[0].size(); i++) {
234  result[i] = _result[0][i];
235  }
236  }
237  } catch (std::exception& e) {
238  CoolProp::set_error_string(e.what());
239  } catch (...) {
240  CoolProp::set_error_string("Undefined error");
241  }
242 }
243 EXPORT_CODE double CONVENTION PropsSI(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* FluidName) {
244  fpu_reset_guard guard;
245  return CoolProp::PropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
246 }
247 EXPORT_CODE void CONVENTION PropsSImulti(const char* Outputs, const char* Name1, double* Prop1, const long size_Prop1, const char* Name2,
248  double* Prop2, const long size_Prop2, char* backend, const char* FluidNames, const double* fractions,
249  const long length_fractions, double* result, long* resdim1, long* resdim2) {
250  fpu_reset_guard guard;
251  try {
252  // Outputs is a delimited string separated by LIST_STRING_DELIMITER
253  std::string delim = CoolProp::get_config_string(LIST_STRING_DELIMITER);
254  // strsplit only support char delimiter
255  if (delim.length() > 1)
256  throw CoolProp::ValueError(format("Length of string delimiter [%d] is bigger than 1 [%d]", delim.length(), delim.size()));
257  std::vector<std::string> _outputs = strsplit(Outputs, delim[0]);
258  if (size_Prop1 != size_Prop2)
259  throw CoolProp::ValueError(
260  format("Length of input parameter 1 [%d] is not equal to length of input parameter 2 [%d]", size_Prop1, size_Prop2));
261  // make vectors out of double pointer
262  std::vector<double> _prop1(Prop1, Prop1 + size_Prop1);
263  std::vector<double> _prop2(Prop2, Prop2 + size_Prop2);
264  // FluidNames is a delimited string separated by LIST_STRING_DELIMITER
265  std::vector<std::string> _fluidNames = strsplit(FluidNames, delim[0]);
266  if (_fluidNames.size() != length_fractions)
267  throw CoolProp::ValueError(
268  format("Length of fractions vector [%d] is not equal to length of fluidNames vector [%d]", _fluidNames.size(), length_fractions));
269  std::vector<double> _fractions(fractions, fractions + length_fractions);
270  std::vector<std::vector<double>> _result =
271  CoolProp::PropsSImulti(_outputs, std::string(Name1), _prop1, std::string(Name2), _prop2, backend, _fluidNames, _fractions);
272  // if CoolProp::PropsSImulti fails it will return an empty vector -> set result dimensions to 0
273  if (_result.size() == 0) {
274  *resdim1 = 0;
275  *resdim2 = 0;
276  } else {
277  if (_result.size() > *resdim1 || _result[0].size() > *resdim2)
278  throw CoolProp::ValueError(
279  format("Result matrix [%d x %d] is bigger than allocated memory [%d x %d]", _result.size(), _result[0].size(), *resdim1, *resdim2));
280  *resdim1 = _result.size();
281  *resdim2 = _result[0].size();
282  for (int i = 0; i < _result.size(); i++) {
283  for (int j = 0; j < _result[i].size(); j++) {
284  result[j + _result[i].size() * i] = _result[i][j];
285  }
286  }
287  }
288  } catch (std::exception& e) {
289  // set result dimensions to 0 to signalize, an error occured
290  *resdim1 = 0;
291  *resdim2 = 0;
292  CoolProp::set_error_string(e.what());
293  } catch (...) {
294  // set result dimensions to 0 to signalize, an error occured
295  *resdim1 = 0;
296  *resdim2 = 0;
297  CoolProp::set_error_string("Undefined error");
298  }
299 }
300 EXPORT_CODE long CONVENTION PhaseSI(const char* Name1, double Prop1, const char* Name2, double Prop2, const char* FluidName, char* phase, int n) {
301  fpu_reset_guard guard;
302  try {
303  std::string s = CoolProp::PhaseSI(std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(FluidName));
304  str2buf(s, phase, n);
305  return 1;
306  } catch (std::exception& e) {
307  CoolProp::set_error_string(e.what());
308  } catch (...) {
309  CoolProp::set_error_string("Undefined error");
310  }
311  return 0;
312 }
313 /*
314  * EXPORT_CODE double CONVENTION PropsSIZ(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, const double *z, int n)
315 {
316  std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
317  double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName, std::vector<double>(z, z+n));
318  reset_fpu();
319  return val;
320 }
321  * */
322 EXPORT_CODE void CONVENTION propssi_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
323  const char* FluidName, double* output) {
324  *output = PropsSI(Output, Name1, *Prop1, Name2, *Prop2, FluidName);
325 }
326 
327 EXPORT_CODE double CONVENTION K2F(double T) {
328  return T * 9 / 5 - 459.67;
329 }
330 EXPORT_CODE double CONVENTION F2K(double T_F) {
331  return (T_F + 459.67) * 5 / 9;
332 }
334  return CoolProp::get_debug_level();
335 }
338 }
339 EXPORT_CODE long CONVENTION get_param_index(const char* param) {
340  try {
341  return CoolProp::get_parameter_index(param);
342  } catch (std::exception& e) {
343  CoolProp::set_error_string(e.what());
344  } catch (...) {
345  CoolProp::set_error_string("Undefined error");
346  }
347  return -1;
348 }
350  try {
351  return CoolProp::get_input_pair_index(pair);
352  } catch (std::exception& e) {
353  CoolProp::set_error_string(e.what());
354  } catch (...) {
355  CoolProp::set_error_string("Undefined error");
356  }
357  return -1;
358 }
359 EXPORT_CODE long CONVENTION get_global_param_string(const char* param, char* Output, int n) {
360  try {
361  std::string s = CoolProp::get_global_param_string(param);
362  str2buf(s, Output, n);
363  return 1;
364  } catch (std::exception& e) {
365  CoolProp::set_error_string(e.what());
366  } catch (...) {
367  CoolProp::set_error_string("Undefined error");
368  }
369  return 0;
370 }
371 EXPORT_CODE long CONVENTION get_parameter_information_string(const char* param, char* Output, int n) {
372  try {
373  int key = CoolProp::get_parameter_index(param);
374  std::string s = CoolProp::get_parameter_information(key, Output);
375  str2buf(s, Output, n);
376  return 1;
377  } catch (std::exception& e) {
378  // if param is wrong, CoolProp::get_parameter_index throws string like
379  // "Your input name [%s] is not valid in get_parameter_index (names are case sensitive)"
380  // CoolProp::get_parameter_information throws string like
381  // "Bad info string [%s] to get_parameter_information" (if Output is wrong)
382  // or "Unable to match the key [%d] in get_parameter_information for info [%s]"
383  // (see src/DataStructures.cpp)
384  // if n is too small, str2buf throws string
385  // "Buffer size is too small"
386  CoolProp::set_error_string(format("get_parameter_information_string(\"%s\", \"%s\", %d): %s", param, Output, n, e.what()));
387  } catch (...) {
388  CoolProp::set_error_string(format("get_parameter_information_string(\"%s\", \"%s\", %d): Undefined error", param, Output, n));
389  }
390  return 0;
391 }
392 EXPORT_CODE long CONVENTION get_fluid_param_string(const char* fluid, const char* param, char* Output, int n) {
393  try {
394  std::string s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param));
395  str2buf(s, Output, n);
396  return 1;
397  } catch (std::exception& e) {
398  CoolProp::set_error_string(e.what());
399  } catch (...) {
400  CoolProp::set_error_string("Undefined error");
401  }
402  return 0;
403 }
404 EXPORT_CODE void CONVENTION set_config_string(const char* key, const char* val) {
405  try {
406  CoolProp::set_config_string(CoolProp::config_string_to_key(std::string(key)), std::string(val));
407  } catch (std::exception& e) {
408  CoolProp::set_error_string(e.what());
409  } catch (...) {
410  CoolProp::set_error_string("Undefined error");
411  }
412 }
413 EXPORT_CODE void CONVENTION set_config_double(const char* key, const double val) {
414  try {
416  } catch (std::exception& e) {
417  CoolProp::set_error_string(e.what());
418  } catch (...) {
419  CoolProp::set_error_string("Undefined error");
420  }
421 }
422 EXPORT_CODE void CONVENTION set_config_bool(const char* key, const bool val) {
423  try {
425  } catch (std::exception& e) {
426  CoolProp::set_error_string(e.what());
427  } catch (...) {
428  CoolProp::set_error_string("Undefined error");
429  }
430 }
431 EXPORT_CODE void CONVENTION set_departure_functions(const char* string_data, long* errcode, char* message_buffer, const long buffer_length) {
432  *errcode = 0;
433  try {
435  } catch (...) {
436  HandleException(errcode, message_buffer, buffer_length);
437  }
438 }
439 EXPORT_CODE double CONVENTION HAPropsSI(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Name3,
440  double Prop3) {
441  fpu_reset_guard guard;
442  return HumidAir::HAPropsSI(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
443 }
444 EXPORT_CODE double CONVENTION cair_sat(double T) {
445  fpu_reset_guard guard;
446  return HumidAir::cair_sat(T);
447 }
448 EXPORT_CODE void CONVENTION hapropssi_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
449  const char* Name3, const double* Prop3, double* output) {
450  *output = HAPropsSI(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
451 }
452 EXPORT_CODE double CONVENTION HAProps(const char* Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char* Name3,
453  double Prop3) {
454  fpu_reset_guard guard;
455  try {
456  return HumidAir::HAProps(std::string(Output), std::string(Name1), Prop1, std::string(Name2), Prop2, std::string(Name3), Prop3);
457  } catch (std::exception& e) {
458  CoolProp::set_error_string(e.what());
459  } catch (...) {
460  CoolProp::set_error_string("Undefined error");
461  }
462  return _HUGE;
463 }
464 EXPORT_CODE void CONVENTION haprops_(const char* Output, const char* Name1, const double* Prop1, const char* Name2, const double* Prop2,
465  const char* Name3, const double* Prop3, double* output) {
466  *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
467 }
469 {
470  private:
471  std::map<std::size_t, shared_ptr<CoolProp::AbstractState>> ASlibrary;
472  long next_handle;
473 
474  public:
475  AbstractStateLibrary() : next_handle(0){};
476  long add(shared_ptr<CoolProp::AbstractState> AS) {
477  ASlibrary.insert(std::pair<std::size_t, shared_ptr<CoolProp::AbstractState>>(this->next_handle, AS));
478  this->next_handle++;
479  return next_handle - 1;
480  }
481  void remove(long handle) {
482  std::size_t count_removed = ASlibrary.erase(handle);
483  if (count_removed != 1) {
484  throw CoolProp::HandleError("could not free handle");
485  }
486  }
487  shared_ptr<CoolProp::AbstractState>& get(long handle) {
488  std::map<std::size_t, shared_ptr<CoolProp::AbstractState>>::iterator it = ASlibrary.find(handle);
489  if (it != ASlibrary.end()) {
490  return it->second;
491  } else {
492  throw CoolProp::HandleError("could not get handle");
493  }
494  }
495 };
496 static AbstractStateLibrary handle_manager;
497 
498 EXPORT_CODE long CONVENTION AbstractState_factory(const char* backend, const char* fluids, long* errcode, char* message_buffer,
499  const long buffer_length) {
500  *errcode = 0;
501  try {
502  shared_ptr<CoolProp::AbstractState> AS(CoolProp::AbstractState::factory(backend, fluids));
503  return handle_manager.add(AS);
504  } catch (...) {
505  HandleException(errcode, message_buffer, buffer_length);
506  }
507  return -1;
508 }
509 EXPORT_CODE void CONVENTION AbstractState_fluid_names(const long handle, char* fluids, long* errcode, char* message_buffer,
510  const long buffer_length) {
511  *errcode = 0;
512 
513  try {
514  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
515  std::vector<std::string> _fluids = AS->fluid_names();
516  std::string fluidsstring = strjoin(_fluids, CoolProp::get_config_string(LIST_STRING_DELIMITER));
517  if (fluidsstring.size() < static_cast<std::size_t>(buffer_length)) {
518  strcpy(fluids, fluidsstring.c_str());
519  } else {
520  throw CoolProp::ValueError(format("Length of string [%d] is greater than allocated buffer length [%d]", fluidsstring.size(),
521  static_cast<std::size_t>(buffer_length)));
522  }
523 
524  } catch (...) {
525  HandleException(errcode, message_buffer, buffer_length);
526  }
527 }
528 EXPORT_CODE void CONVENTION AbstractState_free(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
529  *errcode = 0;
530  try {
531  handle_manager.remove(handle);
532  } catch (...) {
533  HandleException(errcode, message_buffer, buffer_length);
534  }
535 }
536 EXPORT_CODE void CONVENTION AbstractState_set_fractions(const long handle, const double* fractions, const long N, long* errcode, char* message_buffer,
537  const long buffer_length) {
538  *errcode = 0;
539  std::vector<double> _fractions(fractions, fractions + N);
540  try {
541  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
542  if (AS->using_mole_fractions()) {
543  AS->set_mole_fractions(_fractions);
544  } else if (AS->using_mass_fractions()) {
545  AS->set_mass_fractions(_fractions);
546  } else if (AS->using_volu_fractions()) {
547  AS->set_volu_fractions(_fractions);
548  }
549  } catch (...) {
550  HandleException(errcode, message_buffer, buffer_length);
551  }
552 }
553 EXPORT_CODE void CONVENTION AbstractState_get_mole_fractions(const long handle, double* fractions, const long maxN, long* N, long* errcode,
554  char* message_buffer, const long buffer_length) {
555  *errcode = 0;
556 
557  try {
558  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
559  std::vector<double> _fractions = AS->get_mole_fractions();
560  *N = _fractions.size();
561  if (*N <= maxN) {
562  for (int i = 0; i < *N; i++)
563  fractions[i] = _fractions[i];
564  } else {
565  throw CoolProp::ValueError(format("Length of array [%d] is greater than allocated buffer length [%d]", *N, maxN));
566  }
567  } catch (...) {
568  HandleException(errcode, message_buffer, buffer_length);
569  }
570 }
571 EXPORT_CODE void CONVENTION AbstractState_get_mole_fractions_satState(const long handle, const char* saturated_state, double* fractions,
572  const long maxN, long* N, long* errcode, char* message_buffer,
573  const long buffer_length) {
574  *errcode = 0;
575 
576  try {
577  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
578  std::vector<double> _fractions;
579  double quality = AS->Q();
580  std::string string_state(saturated_state);
581  if (0 <= quality && quality <= 1) {
582  if (string_state == "liquid") {
583  _fractions = AS->mole_fractions_liquid();
584  } else if (string_state == "gas") {
585  _fractions = AS->mole_fractions_vapor();
586  } else {
587  throw CoolProp::ValueError(
588  format("Bad info string [%s] to saturated state mole fractions, options are \"liquid\" and \"gas\"", saturated_state));
589  }
590  } else {
591  throw CoolProp::ValueError(format("AbstractState_get_mole_fractions_satState only returns outputs for saturated states if AbstractState "
592  "quality [%g] is within two-phase region (0 <= quality <= 1)",
593  static_cast<double>(quality)));
594  }
595  *N = _fractions.size();
596  if (*N <= maxN) {
597  for (int i = 0; i < *N; i++) {
598  fractions[i] = _fractions[i];
599  }
600  } else {
601  throw CoolProp::ValueError(format("Length of array [%d] is greater than allocated buffer length [%d]", *N, maxN));
602  }
603  } catch (...) {
604  HandleException(errcode, message_buffer, buffer_length);
605  }
606 }
607 EXPORT_CODE double CONVENTION AbstractState_get_fugacity(const long handle, const long i, long* errcode, char* message_buffer,
608  const long buffer_length) {
609  *errcode = 0;
610  try {
611  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
612  return AS->fugacity(i);
613  } catch (...) {
614  HandleException(errcode, message_buffer, buffer_length);
615  }
616  return _HUGE;
617 }
618 EXPORT_CODE double CONVENTION AbstractState_get_fugacity_coefficient(const long handle, const long i, long* errcode, char* message_buffer,
619  const long buffer_length) {
620  *errcode = 0;
621  try {
622  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
623  return AS->fugacity_coefficient(i);
624  } catch (...) {
625  HandleException(errcode, message_buffer, buffer_length);
626  }
627  return _HUGE;
628 }
629 EXPORT_CODE void CONVENTION AbstractState_update(const long handle, const long input_pair, const double value1, const double value2, long* errcode,
630  char* message_buffer, const long buffer_length) {
631  *errcode = 0;
632  try {
633  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
634  AS->update(static_cast<CoolProp::input_pairs>(input_pair), value1, value2);
635  } catch (...) {
636  HandleException(errcode, message_buffer, buffer_length);
637  }
638 }
639 EXPORT_CODE void CONVENTION AbstractState_specify_phase(const long handle, const char* phase, long* errcode, char* message_buffer,
640  const long buffer_length) {
641  *errcode = 0;
642  try {
643  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
644  return AS->specify_phase(CoolProp::get_phase_index(std::string(phase)));
645  } catch (...) {
646  HandleException(errcode, message_buffer, buffer_length);
647  }
648 }
649 EXPORT_CODE void CONVENTION AbstractState_unspecify_phase(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
650  *errcode = 0;
651  try {
652  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
653  return AS->unspecify_phase();
654  } catch (...) {
655  HandleException(errcode, message_buffer, buffer_length);
656  }
657 }
658 EXPORT_CODE double CONVENTION AbstractState_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
659  const long buffer_length) {
660  *errcode = 0;
661  try {
662  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
663  return AS->keyed_output(static_cast<CoolProp::parameters>(param));
664  } catch (...) {
665  HandleException(errcode, message_buffer, buffer_length);
666  }
667  return _HUGE;
668 }
669 
670 EXPORT_CODE double CONVENTION AbstractState_first_saturation_deriv(const long handle, const long Of, const long Wrt, long* errcode,
671  char* message_buffer, const long buffer_length) {
672  *errcode = 0;
673  try {
674  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
675  return AS->first_saturation_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt));
676  } catch (...) {
677  HandleException(errcode, message_buffer, buffer_length);
678  }
679  return _HUGE;
680 }
681 
682 EXPORT_CODE double CONVENTION AbstractState_first_partial_deriv(const long handle, const long Of, const long Wrt, const long Constant, long* errcode,
683  char* message_buffer, const long buffer_length) {
684  *errcode = 0;
685  try {
686  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
687  return AS->first_partial_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
688  static_cast<CoolProp::parameters>(Constant));
689  } catch (...) {
690  HandleException(errcode, message_buffer, buffer_length);
691  }
692  return _HUGE;
693 }
694 
695 EXPORT_CODE double CONVENTION AbstractState_second_partial_deriv(const long handle, const long Of1, const long Wrt1, const long Constant1,
696  const long Wrt2, const long Constant2, long* errcode, char* message_buffer,
697  const long buffer_length) {
698  *errcode = 0;
699  try {
700  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
701  return AS->second_partial_deriv(static_cast<CoolProp::parameters>(Of1), static_cast<CoolProp::parameters>(Wrt1),
702  static_cast<CoolProp::parameters>(Constant1), static_cast<CoolProp::parameters>(Wrt2),
703  static_cast<CoolProp::parameters>(Constant2));
704  } catch (...) {
705  HandleException(errcode, message_buffer, buffer_length);
706  }
707  return _HUGE;
708 }
709 
710 EXPORT_CODE double CONVENTION AbstractState_second_two_phase_deriv(const long handle, const long Of1, const long Wrt1, const long Constant1,
711  const long Wrt2, const long Constant2, long* errcode, char* message_buffer,
712  const long buffer_length) {
713  *errcode = 0;
714  try {
715  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
716  return AS->second_two_phase_deriv(static_cast<CoolProp::parameters>(Of1), static_cast<CoolProp::parameters>(Wrt1),
717  static_cast<CoolProp::parameters>(Constant1), static_cast<CoolProp::parameters>(Wrt2),
718  static_cast<CoolProp::parameters>(Constant2));
719  } catch (...) {
720  HandleException(errcode, message_buffer, buffer_length);
721  }
722  return _HUGE;
723 }
724 
725 EXPORT_CODE double CONVENTION AbstractState_first_two_phase_deriv(const long handle, const long Of, const long Wrt, const long Constant,
726  long* errcode, char* message_buffer, const long buffer_length) {
727  *errcode = 0;
728  try {
729  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
730  return AS->first_two_phase_deriv(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
731  static_cast<CoolProp::parameters>(Constant));
732  } catch (...) {
733  HandleException(errcode, message_buffer, buffer_length);
734  }
735  return _HUGE;
736 }
737 
738 EXPORT_CODE double CONVENTION AbstractState_first_two_phase_deriv_splined(const long handle, const long Of, const long Wrt, const long Constant,
739  const double x_end, long* errcode, char* message_buffer,
740  const long buffer_length) {
741  *errcode = 0;
742  try {
743  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
744  return AS->first_two_phase_deriv_splined(static_cast<CoolProp::parameters>(Of), static_cast<CoolProp::parameters>(Wrt),
745  static_cast<CoolProp::parameters>(Constant), x_end);
746  } catch (...) {
747  HandleException(errcode, message_buffer, buffer_length);
748  }
749  return _HUGE;
750 }
751 
752 
753 EXPORT_CODE void CONVENTION AbstractState_update_and_common_out(const long handle, const long input_pair, const double* value1, const double* value2,
754  const long length, double* T, double* p, double* rhomolar, double* hmolar,
755  double* smolar, long* errcode, char* message_buffer, const long buffer_length) {
756  *errcode = 0;
757  try {
758  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
759 
760  for (int i = 0; i < length; i++) {
761  try {
762  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
763  *(T + i) = AS->T();
764  *(p + i) = AS->p();
765  *(rhomolar + i) = AS->rhomolar();
766  *(hmolar + i) = AS->hmolar();
767  *(smolar + i) = AS->smolar();
768  } catch (...) {
769  }
770  };
771  } catch (...) {
772  HandleException(errcode, message_buffer, buffer_length);
773  }
774 }
775 
776 EXPORT_CODE void CONVENTION AbstractState_update_and_1_out(const long handle, const long input_pair, const double* value1, const double* value2,
777  const long length, const long output, double* out, long* errcode, char* message_buffer,
778  const long buffer_length) {
779  *errcode = 0;
780  try {
781  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
782 
783  for (int i = 0; i < length; i++) {
784  try {
785  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
786  *(out + i) = AS->keyed_output(static_cast<CoolProp::parameters>(output));
787  } catch (...) {
788  }
789  };
790  } catch (...) {
791  HandleException(errcode, message_buffer, buffer_length);
792  }
793 }
794 
795 EXPORT_CODE void CONVENTION AbstractState_update_and_5_out(const long handle, const long input_pair, const double* value1, const double* value2,
796  const long length, long* outputs, double* out1, double* out2, double* out3, double* out4,
797  double* out5, long* errcode, char* message_buffer, const long buffer_length) {
798  *errcode = 0;
799  try {
800  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
801 
802  for (int i = 0; i < length; i++) {
803  try {
804  AS->update(static_cast<CoolProp::input_pairs>(input_pair), *(value1 + i), *(value2 + i));
805  *(out1 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[0]));
806  *(out2 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[1]));
807  *(out3 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[2]));
808  *(out4 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[3]));
809  *(out5 + i) = AS->keyed_output(static_cast<CoolProp::parameters>(outputs[4]));
810  } catch (...) {
811  }
812  };
813  } catch (...) {
814  HandleException(errcode, message_buffer, buffer_length);
815  }
816 }
817 
818 EXPORT_CODE void CONVENTION AbstractState_set_binary_interaction_double(const long handle, const long i, const long j, const char* parameter,
819  const double value, long* errcode, char* message_buffer,
820  const long buffer_length) {
821  *errcode = 0;
822  try {
823  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
824  AS->set_binary_interaction_double(static_cast<std::size_t>(i), static_cast<std::size_t>(j), parameter, value);
825  } catch (...) {
826  HandleException(errcode, message_buffer, buffer_length);
827  }
828 }
829 
830 EXPORT_CODE void CONVENTION AbstractState_set_cubic_alpha_C(const long handle, const long i, const char* parameter, const double c1, const double c2,
831  const double c3, long* errcode, char* message_buffer, const long buffer_length) {
832  *errcode = 0;
833  try {
834  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
835  AS->set_cubic_alpha_C(static_cast<std::size_t>(i), parameter, c1, c2, c3);
836  } catch (...) {
837  HandleException(errcode, message_buffer, buffer_length);
838  }
839 }
840 
841 EXPORT_CODE void CONVENTION AbstractState_set_fluid_parameter_double(const long handle, const long i, const char* parameter, const double value,
842  long* errcode, char* message_buffer, const long buffer_length) {
843  *errcode = 0;
844  try {
845  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
846  AS->set_fluid_parameter_double(static_cast<std::size_t>(i), parameter, value);
847  } catch (...) {
848  HandleException(errcode, message_buffer, buffer_length);
849  }
850 }
851 
852 EXPORT_CODE void CONVENTION AbstractState_build_phase_envelope(const long handle, const char* level, long* errcode, char* message_buffer,
853  const long buffer_length) {
854  *errcode = 0;
855  try {
856  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
857  AS->build_phase_envelope(level);
858  } catch (...) {
859  HandleException(errcode, message_buffer, buffer_length);
860  }
861 }
862 
863 EXPORT_CODE void CONVENTION AbstractState_get_phase_envelope_data(const long handle, const long length, double* T, double* p, double* rhomolar_vap,
864  double* rhomolar_liq, double* x, double* y, long* errcode, char* message_buffer,
865  const long buffer_length) {
866  *errcode = 0;
867  try {
868  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
869  CoolProp::PhaseEnvelopeData pe = AS->get_phase_envelope_data();
870  if (pe.T.size() > static_cast<std::size_t>(length)) {
871  throw CoolProp::ValueError(format("Length of phase envelope vectors [%d] is greater than allocated buffer length [%d]",
872  static_cast<int>(pe.T.size()), static_cast<int>(length)));
873  }
874  std::size_t N = pe.x.size();
875  for (std::size_t i = 0; i < pe.T.size(); i++) {
876  *(T + i) = pe.T[i];
877  *(p + i) = pe.p[i];
878  *(rhomolar_vap + i) = pe.rhomolar_vap[i];
879  *(rhomolar_liq + i) = pe.rhomolar_liq[i];
880  for (std::size_t j = 0; j < N; ++j) {
881  *(x + i * N + j) = pe.x[j][i];
882  *(y + i * N + j) = pe.y[j][i];
883  }
884  }
885  } catch (...) {
886  HandleException(errcode, message_buffer, buffer_length);
887  }
888 }
889 
890 EXPORT_CODE void CONVENTION AbstractState_get_phase_envelope_data_checkedMemory(const long handle, const long length, const long maxComponents, double* T,
891  double* p, double* rhomolar_vap, double* rhomolar_liq, double* x, double* y,
892  long* actual_length, long* actual_components, long* errcode, char* message_buffer,
893  const long buffer_length) {
894  *errcode = 0;
895  try {
896  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
897  CoolProp::PhaseEnvelopeData pe = AS->get_phase_envelope_data();
898  *actual_length = pe.T.size();
899  if (pe.T.size() > static_cast<std::size_t>(length)) {
900  throw CoolProp::ValueError(format("Length of phase envelope vectors [%d] is greater than allocated buffer length [%d]",
901  static_cast<int>(pe.T.size()), static_cast<int>(length)));
902  }
903  *actual_components = pe.x.size();
904  if (*actual_components > static_cast<std::size_t>(maxComponents)) {
905  throw CoolProp::ValueError(format("Length of phase envelope composition vectors [%d] is greater than allocated buffer length [%d]",
906  static_cast<int>(*actual_components), static_cast<int>(maxComponents)));
907  }
908  for (std::size_t i = 0; i < pe.T.size(); i++) {
909  *(T + i) = pe.T[i];
910  *(p + i) = pe.p[i];
911  *(rhomolar_vap + i) = pe.rhomolar_vap[i];
912  *(rhomolar_liq + i) = pe.rhomolar_liq[i];
913  for (std::size_t j = 0; j < *actual_components; ++j) {
914  *(x + i * *actual_components + j) = pe.x[j][i];
915  *(y + i * *actual_components + j) = pe.y[j][i];
916  }
917  }
918  } catch (...) {
919  HandleException(errcode, message_buffer, buffer_length);
920  }
921 }
922 
923 EXPORT_CODE void CONVENTION AbstractState_build_spinodal(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
924  *errcode = 0;
925  try {
926  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
927  AS->build_spinodal();
928  } catch (...) {
929  HandleException(errcode, message_buffer, buffer_length);
930  }
931 }
932 
933 EXPORT_CODE void CONVENTION AbstractState_get_spinodal_data(const long handle, const long length, double* tau, double* delta, double* M1,
934  long* errcode, char* message_buffer, const long buffer_length) {
935  *errcode = 0;
936  try {
937  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
938  CoolProp::SpinodalData spin = AS->get_spinodal_data();
939  if (spin.tau.size() > static_cast<std::size_t>(length)) {
940  throw CoolProp::ValueError(format("Length of spinodal vectors [%d] is greater than allocated buffer length [%d]",
941  static_cast<int>(spin.tau.size()), static_cast<int>(length)));
942  }
943  for (std::size_t i = 0; i < spin.tau.size(); ++i) {
944  *(tau + i) = spin.tau[i];
945  *(delta + i) = spin.delta[i];
946  *(M1 + i) = spin.M1[i];
947  }
948  } catch (...) {
949  HandleException(errcode, message_buffer, buffer_length);
950  }
951 }
952 
953 EXPORT_CODE void CONVENTION AbstractState_all_critical_points(const long handle, long length, double* T, double* p, double* rhomolar, long* stable,
954  long* errcode, char* message_buffer, const long buffer_length) {
955  *errcode = 0;
956  try {
957  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
958  std::vector<CoolProp::CriticalState> pts = AS->all_critical_points();
959  if (pts.size() > static_cast<std::size_t>(length)) {
960  throw CoolProp::ValueError(format("Length of critical point vector [%d] is greater than allocated buffer length [%d]",
961  static_cast<int>(pts.size()), static_cast<int>(length)));
962  }
963  for (std::size_t i = 0; i < pts.size(); ++i) {
964  *(T + i) = pts[i].T;
965  *(p + i) = pts[i].p;
966  *(rhomolar + i) = pts[i].rhomolar;
967  *(stable + i) = pts[i].stable;
968  }
969  } catch (...) {
970  HandleException(errcode, message_buffer, buffer_length);
971  }
972 }
973 
974 EXPORT_CODE double CONVENTION AbstractState_keyed_output_satState(const long handle, const char* saturated_state, const long param, long* errcode,
975  char* message_buffer, const long buffer_length) {
976  *errcode = 0;
977 
978  try {
979  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
980  double quality = AS->Q();
981  std::string string_state(saturated_state);
982  if (0 <= quality && quality <= 1) {
983  if (string_state == "liquid") {
984  return AS->saturated_liquid_keyed_output(static_cast<CoolProp::parameters>(param));
985  } else if (string_state == "gas") {
986  return AS->saturated_vapor_keyed_output(static_cast<CoolProp::parameters>(param));
987  } else {
988  throw CoolProp::ValueError(
989  format("Bad info string [%s] to saturated state output, options are \"liquid\" and \"gas\"", saturated_state));
990  }
991  } else {
992  throw CoolProp::ValueError(format("AbstractState_keyed_output_satState only returns outputs for saturated states if AbstractState "
993  "quality [%g] is within two-phase region (0 <= quality <= 1)",
994  static_cast<double>(quality)));
995  }
996  } catch (...) {
997  HandleException(errcode, message_buffer, buffer_length);
998  return _HUGE;
999  }
1000 }
1001 
1002 EXPORT_CODE void CONVENTION AbstractState_backend_name(const long handle, char* backend, long* errcode, char* message_buffer,
1003  const long buffer_length) {
1004  *errcode = 0;
1005 
1006  try {
1007  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1008  std::string backendstring = AS->backend_name();
1009  if (backendstring.size() < static_cast<std::size_t>(buffer_length)) {
1010  strcpy(backend, backendstring.c_str());
1011  } else {
1012  throw CoolProp::ValueError(format("Length of string [%d] is greater than allocated buffer length [%d]", backendstring.size(),
1013  static_cast<std::size_t>(buffer_length)));
1014  }
1015  } catch (...) {
1016  HandleException(errcode, message_buffer, buffer_length);
1017  }
1018 }
1019 
1020 EXPORT_CODE int CONVENTION AbstractState_phase(const long handle, long* errcode, char* message_buffer, const long buffer_length) {
1021  *errcode = 0;
1022  try {
1023  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1024  return AS->phase();
1025  } catch (...) {
1026  HandleException(errcode, message_buffer, buffer_length);
1027  }
1028  return -1;
1029 }
1030 
1031 EXPORT_CODE void CONVENTION AbstractState_fluid_param_string(const long handle, const char* param, char* return_buffer,
1032  const long return_buffer_length, long* errcode, char* message_buffer,
1033  const long buffer_length) {
1034  *errcode = 0;
1035  try {
1036  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1037  std::string temp = AS->fluid_param_string(param);
1038  if (temp.size() < static_cast<std::size_t>(return_buffer_length)) {
1039  strcpy(return_buffer, temp.c_str());
1040  } else {
1041  *errcode = 2;
1042  }
1043  } catch (...) {
1044  HandleException(errcode, message_buffer, buffer_length);
1045  }
1046 }
1047 
1048 EXPORT_CODE double CONVENTION AbstractState_saturated_liquid_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
1049  const long buffer_length) {
1050  *errcode = 0;
1051  try {
1052  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1053  return AS->saturated_liquid_keyed_output(static_cast<CoolProp::parameters>(param));
1054  } catch (...) {
1055  HandleException(errcode, message_buffer, buffer_length);
1056  }
1057  return _HUGE;
1058 }
1059 
1060 EXPORT_CODE double CONVENTION AbstractState_saturated_vapor_keyed_output(const long handle, const long param, long* errcode, char* message_buffer,
1061  const long buffer_length) {
1062  *errcode = 0;
1063  try {
1064  shared_ptr<CoolProp::AbstractState>& AS = handle_manager.get(handle);
1065  return AS->saturated_vapor_keyed_output(static_cast<CoolProp::parameters>(param));
1066  } catch (...) {
1067  HandleException(errcode, message_buffer, buffer_length);
1068  }
1069  return _HUGE;
1070 }
1071 
1072 EXPORT_CODE void CONVENTION add_fluids_as_JSON(const char* backend, const char* fluidstring, long* errcode, char* message_buffer,
1073  const long buffer_length) {
1074  *errcode = 0;
1075 
1076  try {
1077  CoolProp::add_fluids_as_JSON(backend, fluidstring);
1078  } catch (...) {
1079  HandleException(errcode, message_buffer, buffer_length);
1080  }
1081 }
1082 
1083 EXPORT_CODE int CONVENTION C_is_valid_fluid_string(const char* fluidName) {
1084  return CoolProp::is_valid_fluid_string(fluidName);
1085 }
1086 
1087 EXPORT_CODE int CONVENTION C_extract_backend(const char* fluid_string, char* backend, const long backend_length, char* fluid,
1088  const long fluid_length) {
1089  std::string _fluid, _backend;
1090  CoolProp::extract_backend(fluid_string, _backend, _fluid);
1091  if (_backend.size() < static_cast<std::size_t>(backend_length)) {
1092  strcpy(backend, _backend.c_str());
1093  } else {
1094  return -1;
1095  }
1096  if (_fluid.size() < static_cast<std::size_t>(fluid_length)) {
1097  strcpy(fluid, _fluid.c_str());
1098  } else {
1099  return -1;
1100  }
1101  return 0;
1102 }