2
$\begingroup$

I am trying to include a C++ function into the Mathematica wrapper. There is a void function to change the reference state.

The original wrapper includes the following C++ function.

Here is procedure to get mathematica wrapper (CoolProp.dll).

git clone https://github.com/CoolProp/CoolProp --recursive
cd CoolProp
mkdir build && cd build
cmake .. -DCOOLPROP_MATHEMATICA_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -G 
"Visual Studio 10 2010 Win64"
cmake --build . --config Release

The full procedure and instruction were obtained from here.

http://www.coolprop.org/coolprop/wrappers/Mathematica/index.html#mathematica

The prerequisites are here.

http://www.coolprop.org/coolprop/wrappers/index.html#wrapper-common-prereqs

These are the codes in cpp files for a double function.
double CoolProp::PropsSI ( const std::string & Output, const std::string & Name1, double Prop1, const std::string & Name2, double Prop2, const std::string & FluidName )

The new void function I want to include is as follow.

void CoolProp::set_reference_stateS (   const std::string &     FluidName, const std::string &  reference_state )

The second function takes the first argument as fluid string and the second as the reference state string such as "ASHRAE"

I modified the Mathematica wrapper (CoolPropMathematica.cpp) in the as follows:

/* Include required header */
#include "CoolProp.h"
#include "HumidAirProp.h"
#include "WolframLibrary.h"

/* Return the version of Library Link */
extern "C" DLLEXPORT mint WolframLibrary_getVersion( ) {
return WolframLibraryVersion;
}

/* Initialize Library */
extern "C" DLLEXPORT int WolframLibrary_initialize( WolframLibraryData 
libData) {
return LIBRARY_NO_ERROR;
}

/* Uninitialize Library */
extern "C" DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData 
libData) {
return;
}

/* Adds one to the input, returning the result  */
extern "C" DLLEXPORT int plus_one( WolframLibraryData libData, mint Argc, 
MArgument *Args, MArgument Res) {
mreal I1;
I1 = MArgument_getReal(Args[0]);
MArgument_setReal(Res, I1+1.0);
return LIBRARY_NO_ERROR;
}




extern "C" DLLEXPORT int PropsSI( WolframLibraryData libData, mint Argc, 
MArgument *Args, MArgument Res) {
if (Argc != 6){ return LIBRARY_FUNCTION_ERROR; }
char *outstring = MArgument_getUTF8String(Args[0]);
char *In1string = MArgument_getUTF8String(Args[1]);
mreal In1val = MArgument_getReal(Args[2]);
char *In2string = MArgument_getUTF8String(Args[3]);
mreal In2val = MArgument_getReal(Args[4]);
char *Fluidstring = MArgument_getUTF8String(Args[5]);

// PropsS version takes all strings, not single-character inputs
double val = CoolProp::PropsSI(outstring,In1string,(double)In1val,In2string,(double)In2val,Fluidstring);
MArgument_setReal(Res, val);
return LIBRARY_NO_ERROR;



extern "C" DLLEXPORT int set_reference_stateS( WolframLibraryData 
libData, mint Argc, MArgument *Args, MArgument Res) {
if (Argc != 2){ return LIBRARY_FUNCTION_ERROR; }
char *In1string = MArgument_getUTF8String(Args[0]);
char *In2string = MArgument_getUTF8String(Args[1]);
char *Fluidstring = MArgument_getUTF8String(Args[0]);
char *RefStatestring = MArgument_getUTF8String(Args[1]);    

// set_reference_stateS version takes all strings, not single-character inputs
CoolProp::set_reference_stateS(Fluidstring,RefStatestring);
// MArgument_setChar(Res, val);
return LIBRARY_NO_ERROR;
}

I used these codes in Mathematica to call the functions.

PropsSI = LibraryFunctionLoad["CoolProp", "PropsSI", {UTF8String, UTF8String, Real, UTF8String, Real, UTF8String}, Real]
HAPropsSI = LibraryFunctionLoad["CoolProp", "HAPropsSI", {UTF8String, UTF8String, Real, UTF8String, Real, UTF8String, Real}, Real];


setRefStateS = LibraryFunctionLoad["CoolProp", "set_reference_stateS", {UTF8String, UTF8String}, {}];
setRefStateS[{"n-Propane", "ASHRAE"}]

Print[{PropsSI["H", "T", 233.15, "Q", 0, "n-Propane"], " ASHRAE test h "}]
PropsSI["T", "P", 101325, "Q", 1, "Water"];

LibraryFunctionUnload[PropsSI];
LibraryFunctionUnload[HAPropsSI];
LibraryFunctionUnload[setRefStateS];

These are the outputs from the program.

I managed to general the .dll file, but that particular function doesn't work since it seems the function is not loaded.

LibraryFunctionLoad output

My question is: "Is the codes added to load (set_reference_stateS) function correct?".

Appreciate your help.

$\endgroup$
  • 3
    $\begingroup$ Please give some context, link to the relevant libraries (CoolProp??) and state the question explicitly. "Doesn't work" is not a question. Also, it was not stated what does not work, how it fails, what errors you see, how you compiled and loaded the library, what command you ran when it failed, etc. etc $\endgroup$ – Szabolcs Nov 11 '18 at 14:55
  • $\begingroup$ I have modified the post including all the necessary links and information as suggested. Thank you. $\endgroup$ – yaykhel Nov 12 '18 at 1:55
3
$\begingroup$

I managed to solve this problem.

The correct codes in .cpp file for mathematica wrapper are as follow.

extern "C" DLLEXPORT int set_reference_stateS( WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
if (Argc != 2){ return LIBRARY_FUNCTION_ERROR; }
char *Fluidstring = MArgument_getUTF8String(Args[0]);
char *RefStatestring = MArgument_getUTF8String(Args[1]);    

// set_reference_stateS version takes all strings, not single-character inputs
CoolProp::set_reference_stateS(Fluidstring,RefStatestring);
// MArgument_setChar(Res, val);
return LIBRARY_NO_ERROR;

In Mathematica, we have to call like this:

setRefStateS = LibraryFunctionLoad["CoolProp", 

"set_reference_stateS", {UTF8String, UTF8String}, "Void"];

setRefStateS["n-Propane", "ASHRAE"]

Print[{TestPropsSI["H", "T", 233.15, "Q", 0, "n-Propane"], " ASHRAE test h "}]

setRefStateS["n-Propane", "DEF"]

Print[{TestPropsSI["H", "T", 233.15, "Q", 0, "n-Propane"], " DEF test h "}]

The output is now: (* {-4.88073*10^-12, ASHRAE test h } ) ( {105123., DEF test h } *)

Thank you.

$\endgroup$
2
$\begingroup$

In what you show, the problem is a syntax error in LibraryFunctionLoad. The last argument (the return type) cannot be {}. It must be "Void" for a function that does not return anything.


However, I see some other issues in the code. When a string is passed to a LibraryFunction, it must be manually freed after use. See UTF8String_disown.

As it stands, the function has a memory leak because it does not free the input strings.

$\endgroup$
  • $\begingroup$ Thank you. I have included codes to free the memory. $\endgroup$ – yaykhel Nov 19 '18 at 7:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.