I have been trying to use WSTP to call from C++ (MSVS 2010, Windows 7, 32-bit), a Wolfram Mathematica function in a package which I have created.
From the following link, I understand that the key functions to use are WSLoopbackOpen, WSClose and WSTransferExpression:
http://reference.wolfram.com/language/tutorial/ManipulatingExpressionsInExternalPrograms.html
I started from the 'factor' and 'quotient' examples given in the Windows WSTP Developer Kit, with which I have been successful. Simple examples like "WSPutFunction(link, "Cos", 1); WSPutReal64(link, input)" work fine, but even slightly more complicated examples, with "Cos" replaced by, say "Predict[{2.5->1.0}]", don't seem to work.
That's why I would like to learn how to handle the latter kind of functions, either by first treating those as strings, or, by first saving those in a package, calling the package and then calling the functions defined in the package.
For the last several days, I have been struggling unsuccessfully to make even a simple example work. The above link mentions how the expression Power[x, 3] can be put onto a loopback link, and how the expression can be gotten back from the link. I wish that the documentation had showed a complete example. The Developer Kit also doesn't seem to have such an example.
Are there any simple but complete illustrative example codes available anywhere? Any suggestions would be very helpful. Thanks!
UPDATE on Mon 3/27/17:
Thanks for the responses!
With your help, now I have been able to get the following sample code working:
cout << "Input = "; cin >> input;
WSPutFunction(link, "EvaluatePacket", 1L);
WSPutFunction(link, "ToExpression", 1);
WSPutFunction(link, "StringJoin", 3);
WSPutString(link, "Predict[{2.5->1.0,3.5->2.0}][");
WSPutFunction(link, "ToString", 1);
WSPutReal(link, input);
WSPutString(link, "]");
WSEndPacket(link);
while(WSNextPacket(link) != RETURNPKT)
WSNewPacket(link);
WSGetReal(link, &output);
cout << "Output = " << output << endl;
[By the way, please note that the FullForm of "Predict[{2.5->1.0},...]" actually turns out to be not necessary, as long as WSPutString is used.]
However, when I try to call a package and a function defined therein, it is not working. Please see below:
Mathematica package:
BeginPackage["package`"]
Begin["`Private`"]
predict[x_]:=Predict[{2.5->1.0,3.5->2.0}][x]
End[]
EndPackage[]
WSTP code:
cout << "Input = "; cin >> input;
WSPutFunction(link, "EvaluatePacket", 1L);
WSPutFunction(link, "ToExpression", 1);
WSPutString(link, "<<package`");
WSPutFunction(link, "predict", 1);
WSPutReal(link, input);
while(WSNextPacket(link) != RETURNPKT)
WSNewPacket(link);
WSEndPacket(link);
WSGetReal(link, &output);
cout << "Output = " << output << endl;
[Using the following FullForm for 'Get' did not seem to make a difference:]
WSPutFunction(link, "Get", 1);
WSPutString(link, "package`");
I think now I need to understand how to implement the equivalent of pressing "Shift-Enter", because then I would be able to use the following type of code:
WSPutFunction(link, "StringJoin", 3);
WSPutString(link, "<<package`;[something equivalent of "PRESS SHIFT-ENTER"] predict[")
WSPutFunction(link, "ToString", 1);
WSPutReal(link, input);
WSPutString(link, "]");
I am still rather new to the idea of packets, which I find very interesting. The MathLink Tutorial is great on explaining a lot of the basic concepts! It seems to me, however, that at least some features (besides the simple name-change from 'ML' to 'WS') may have changed in WSTP.
Do I need to end one packet and start another one, after calling the package and before calling the function defined in the package? Can you please help? Thank you.
Predict[{2.5 -> 1.0}]
isPredict[List[Rule[2.5, 1.0]]]
. This means three MLPutFunction calls, the first two with 1 argument, the third with two. Then put two real values using MLPutReal as the final two arguments. $\endgroup$