6
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ Here is some complete code, unfortunately the description is written in Chinese, but the code itself is self-explanatory $\endgroup$ – happy fish Mar 25 '17 at 7:04
  • $\begingroup$ This is the MathLink tutorial to read first. It's old, but better than in the documentation. If you make your question concrete enough, I can help you. As currently written, it is not very well specified and I am not sure what is it specifically that you want to do but cannot. Please give a very simple, but still concrete example of a task. $\endgroup$ – Szabolcs Mar 25 '17 at 10:40
  • $\begingroup$ I presume you understand the full form of expressions. Predict[{2.5 -> 1.0}] is Predict[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$ – Szabolcs Mar 25 '17 at 10:43
  • $\begingroup$ Please see my today's update in the main text. Thanks. $\endgroup$ – math-student Mar 27 '17 at 23:45
  • $\begingroup$ [By the way, I have been using Mathematica version 11.1.] $\endgroup$ – math-student Mar 28 '17 at 0:00
2
$\begingroup$

I have been able to solve the problem just now, by using the following code:

WSPutFunction(link, "ToExpression", 1);
WSPutFunction(link, "StringJoin", 3);
WSPutString(link, "<<package`;package`predict[");
WSPutFunction(link, "ToString", 1);
WSPutReal(link, input);
WSPutString(link, "]");

Thank you very much for your suggestions, help and support!

$\endgroup$

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.