Mathematica 9 is now available
Student Support Forum
-----
Student Support Forum: 'MathLink and Strings' topicStudent Support Forum > General > "MathLink and Strings"

Help | Reply To Topic
Author Comment/Response
Dave Richardson
11/24/99 05:51am

Hello,

I am working with MathLink, and I have a question.

Is String a valid type?

Here is a basic program I am trying to write to read a string (from Mathematica) and make a decision based
upon it. Then I want to return a double based upon this...

Below is: string.cpp ********************************************

#include ''mathlink.h''
#include <string.h>

int main(int argc, char *argv[]){
return MLMain(argc,argv);
}

double whichx(char* sRefrigerant){
double rx;
if (strcoll(sRefrigerant, ''R134a'' ) == 0) rx = 12.;
else rx = 9;
return rx;
}

end string.cpp **************************************************

Here is the Template File string.tm *******************************

:Evaluate: BeginPackage[ ''StringTest`'']
:Evaluate: WrapProps::usage = ''whx(''R134a''), returns 12 if the entered string is R-134a, 9 if not.''


:Evaluate: whx::usage = ''a number''
:Begin:
:Function: whichx
:Pattern: whx[sRefrigerant]
:Arguments: {sRefrigerant}
:ArgumentTypes: {String}
:ReturnType: Real
:End:


:Evaluate: EndPackage[]

::This is a comment line.

end string.cpp **************************************************


According to the Mathematica book, String is a valid argument type in Mathematica (Thus the template file),
and its equivalent in c (c++) is the char*.

For some reason, I am not getting a good link, and thus a crash and burn...

If I change the type to double (In the c++ code and .tm template), I get a compile/link/run just fine.

Can anyone point to the flaw in my logic here, and direct me around the problem?

Thanks,

Dave!


See Below for stringtm.cpp
mprep then successfully generates the stringtm.cpp file ********************

/*
* This file automatically produced by mprep from:
* string.tm
* mprep Revision 7 (c) Copyright Wolfram Research, Inc. 1990-1999
*/

#define MPREP_REVISION 7


#include ''mathlink.h''

int MLAbort = 0;
int MLDone = 0;
long MLSpecialCharacter = '\0';
HANDLE MLInstance = (HANDLE)0;
HWND MLIconWindow = (HWND)0;

MLINK stdlink = 0;
MLEnvironment stdenv = 0;
MLYieldFunctionObject stdyielder = 0;
MLMessageHandlerObject stdhandler = 0;

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#if WIN32_MATHLINK && !defined(_fstrncpy)
# define _fstrncpy strncpy
#endif

#ifndef CALLBACK
#define CALLBACK FAR PASCAL
typedef LONG LRESULT;
typedef unsigned int UINT;
typedef WORD WPARAM;
typedef DWORD LPARAM;
#endif


LRESULT CALLBACK MLEXPORT
IconProcedure( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

LRESULT CALLBACK MLEXPORT
IconProcedure( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg){
case WM_CLOSE:
MLDone = 1;
MLAbort = 1;
break;
case WM_QUERYOPEN:
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam);
}

#define _APISTR(i) #i
#define APISTR(i) _APISTR(i)

HWND MLInitializeIcon( HINSTANCE hInstance, int nCmdShow)
{
char path_name[260], *icon_name;
WNDCLASS wc;
HMODULE hdll;

MLInstance = hInstance;
if( ! nCmdShow) return (HWND)0;
#if WIN16_MATHLINK
hdll = GetModuleHandle( ''ml16i'' APISTR(MLINTERFACE));
#else
hdll = GetModuleHandle( ''ml32i'' APISTR(MLINTERFACE));
#endif

(void)GetModuleFileName( hInstance, path_name, sizeof(path_name));
icon_name = strrchr( path_name, '\\') + 1;
*strchr( icon_name, '.') = '\0';

wc.style = 0;
wc.lpfnWndProc = IconProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
if( hdll)
wc.hIcon = LoadIcon( hdll, ''MLIcon'');
else
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH);
wc.lpszMenuName = (LPSTR) 0;
wc.lpszClassName = ''mprepIcon'';
(void)RegisterClass( &wc);

MLIconWindow = CreateWindow( ''mprepIcon'', icon_name,
WS_OVERLAPPEDWINDOW | WS_MINIMIZE, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
(HWND)0, (HMENU)0, hInstance, (void FAR*)0);

if( MLIconWindow){
ShowWindow( MLIconWindow, SW_MINIMIZE);
UpdateWindow( MLIconWindow);
}
return MLIconWindow;
}


#if __BORLANDC__
#pragma argsused
#endif

MLYDEFN( devyield_result, MLDefaultYielder, ( MLINK mlp, MLYieldParameters yp))
{
MSG msg;

#if !__BORLANDC__
mlp = mlp; /* suppress unused warning */
yp = yp; /* suppress unused warning */
#endif

if( PeekMessage( &msg, (HWND)0, 0, 0, PM_REMOVE)){
TranslateMessage( &msg);
DispatchMessage( &msg);
}
return MLDone;
}


/********************************* end header *********************************/


double whichx P(( kcharp_ct _tp1));

#if MLPROTOTYPES
static int _tr0( MLINK mlp)
#else
static int _tr0(mlp) MLINK mlp;
#endif
{
int res = 0;
double _tp0;
kcharp_ct _tp1;
if ( ! MLGetString( mlp, &_tp1) ) goto L0;
if ( ! MLNewPacket(mlp) ) goto L1;

_tp0 = whichx(_tp1);

res = MLAbort ?
MLPutFunction( mlp, ''Abort'', 0) : MLPutReal( mlp, _tp0);
L1: MLDisownString(mlp, _tp1);

L0: return res;
} /* _tr0 */


static struct func {
int f_nargs;
int manual;
int (*f_func)P((MLINK));
char *f_name;
} _tramps[1] = {
{ 1, 0, _tr0, ''whichx'' }
};

static char* evalstrs[] = {
''BeginPackage[ \''StringTest`\'']'',
(char*)0,
''WrapProps::usage = \''whx(\''R134a\''), returns 12 if the entered stri'',
''ng is R-134a, 9 if not.\'''',
(char*)0,
''whx::usage = \''a number\'''',
(char*)0,
''EndPackage[]'',
(char*)0,
(char*)0
};
#define CARDOF_EVALSTRS 4

static int _definepattern P(( MLINK, char*, char*, int));

static int _doevalstr P(( MLINK, int));

int _MLDoCallPacket P(( MLINK, struct func[], int));


#if MLPROTOTYPES
int MLInstall( MLINK mlp)
#else
int MLInstall(mlp) MLINK mlp;
#endif
{
int _res;
_res = MLConnect(mlp);
if (_res) _res = _doevalstr( mlp, 0);
if (_res) _res = _doevalstr( mlp, 1);
if (_res) _res = _doevalstr( mlp, 2);
if (_res) _res = _definepattern(mlp, ''whx[sRefrigerant]'', ''{sRefrigerant}'', 0);
if (_res) _res = _doevalstr( mlp, 3);
if (_res) _res = MLPutSymbol( mlp, ''End'');
if (_res) _res = MLFlush( mlp);
return _res;
} /* MLInstall */


#if MLPROTOTYPES
int MLDoCallPacket( MLINK mlp)
#else
int MLDoCallPacket( mlp) MLINK mlp;
#endif
{
return _MLDoCallPacket( mlp, _tramps, 1);
} /* MLDoCallPacket */

/******************************* begin trailer ********************************/

#ifndef EVALSTRS_AS_BYTESTRINGS
# define EVALSTRS_AS_BYTESTRINGS 1
#endif

#if CARDOF_EVALSTRS
static int _doevalstr( MLINK mlp, int n)
{
long bytesleft, charsleft, bytesnow;
#if !EVALSTRS_AS_BYTESTRINGS
long charsnow;
#endif
char **s, **p;
char *t;

s = evalstrs;
while( n-- > 0){
if( *s == 0) break;
while( *s++ != 0){}
}
if( *s == 0) return 0;
bytesleft = 0;
charsleft = 0;
p = s;
while( *p){
t = *p; while( *t) ++t;
bytesnow = t - *p;
bytesleft += bytesnow;
charsleft += bytesnow;
#if !EVALSTRS_AS_BYTESTRINGS
t = *p;
charsleft -= MLCharacterOffset( &t, t + bytesnow, bytesnow);
/* assert( t == *p + bytesnow); */
#endif
++p;
}


MLPutNext( mlp, MLTKSTR);
#if EVALSTRS_AS_BYTESTRINGS
p = s;
while( *p){
t = *p; while( *t) ++t;
bytesnow = t - *p;
bytesleft -= bytesnow;
MLPut8BitCharacters( mlp, bytesleft, (unsigned char*)*p, bytesnow);
++p;
}
#else
MLPut7BitCount( mlp, charsleft, bytesleft);
p = s;
while( *p){
t = *p; while( *t) ++t;
bytesnow = t - *p;
bytesleft -= bytesnow;
t = *p;
charsnow = bytesnow - MLCharacterOffset( &t, t + bytesnow, bytesnow);
/* assert( t == *p + bytesnow); */
charsleft -= charsnow;
MLPut7BitCharacters( mlp, charsleft, *p, bytesnow, charsnow);
++p;
}
#endif
return MLError( mlp) == MLEOK;
}
#endif /* CARDOF_EVALSTRS */


static int _definepattern( MLINK mlp, char *patt, char *args, int func_n)
{
MLPutFunction( mlp, ''DefineExternal'', (long)3);
MLPutString( mlp, patt);
MLPutString( mlp, args);
MLPutInteger( mlp, func_n);
return !MLError(mlp);
} /* _definepattern */


int _MLDoCallPacket( MLINK mlp, struct func functable[], int nfuncs)
{
long len;
int n, res = 0;
struct func* funcp;

if( ! MLGetInteger( mlp, &n) || n < 0 || n >= nfuncs) goto L0;
funcp = &functable[n];

if( funcp->f_nargs >= 0
&& ( ! MLCheckFunction(mlp, ''List'', &len)
|| ( !funcp->manual && (len != funcp->f_nargs))
|| ( funcp->manual && (len < funcp->f_nargs))
)
) goto L0;

stdlink = mlp;
res = (*funcp->f_func)( mlp);

L0: if( res == 0)
res = MLClearError( mlp) && MLPutSymbol( mlp, ''$Failed'');
return res && MLEndPacket( mlp) && MLNewPacket( mlp);
} /* _MLDoCallPacket */


mlapi_packet MLAnswer( MLINK mlp)
{
mlapi_packet pkt = 0;

while( !MLDone && !MLError(mlp)
&& (pkt = MLNextPacket(mlp), pkt) && pkt == CALLPKT){
MLAbort = 0;
if( !MLDoCallPacket(mlp)) pkt = 0;
}
MLAbort = 0;
return pkt;
}



/*
Module[ { me = $ParentLink},
$ParentLink = contents of RESUMEPKT;
Message[ MessageName[$ParentLink, ''notfe''], me];
me]
*/

static int refuse_to_be_a_frontend( MLINK mlp)
{
int pkt;

MLPutFunction( mlp, ''EvaluatePacket'', 1);
MLPutFunction( mlp, ''Module'', 2);
MLPutFunction( mlp, ''List'', 1);
MLPutFunction( mlp, ''Set'', 2);
MLPutSymbol( mlp, ''me'');
MLPutSymbol( mlp, ''$ParentLink'');
MLPutFunction( mlp, ''CompoundExpression'', 3);
MLPutFunction( mlp, ''Set'', 2);
MLPutSymbol( mlp, ''$ParentLink'');
MLTransferExpression( mlp, mlp);
MLPutFunction( mlp, ''Message'', 2);
MLPutFunction( mlp, ''MessageName'', 2);
MLPutSymbol( mlp, ''$ParentLink'');
MLPutString( mlp, ''notfe'');
MLPutSymbol( mlp, ''me'');
MLPutSymbol( mlp, ''me'');
MLEndPacket( mlp);

while( (pkt = MLNextPacket( mlp), pkt) && pkt != SUSPENDPKT)
MLNewPacket( mlp);
MLNewPacket( mlp);
return MLError( mlp) == MLEOK;
}


int MLEvaluate( MLINK mlp, charp_ct s)
{
if( MLAbort) return 0;
return MLPutFunction( mlp, ''EvaluatePacket'', 1L)
&& MLPutFunction( mlp, ''ToExpression'', 1L)
&& MLPutString( mlp, s)
&& MLEndPacket( mlp);
}


int MLEvaluateString( MLINK mlp, charp_ct s)
{
int pkt;
if( MLAbort) return 0;
if( MLEvaluate( mlp, s)){
while( (pkt = MLAnswer( mlp), pkt) && pkt != RETURNPKT)
MLNewPacket( mlp);
MLNewPacket( mlp);
}
return MLError( mlp) == MLEOK;
} /* MLEvaluateString */


#if __BORLANDC__
#pragma argsused
#endif

MLMDEFN( void, MLDefaultHandler, ( MLINK mlp, unsigned long message, unsigned long n))
{
#if !__BORLANDC__
mlp = (MLINK)0; /* suppress unused warning */
n = 0; /* suppress unused warning */
#endif

switch (message){
case MLTerminateMessage:
MLDone = 1;
case MLInterruptMessage:
case MLAbortMessage:
MLAbort = 1;
default:
return;
}
}



static int _MLMain( charpp_ct argv, charpp_ct argv_end, charp_ct commandline)
{
MLINK mlp;
long err;

if( !stdenv)
stdenv = MLInitialize( (MLParametersPointer)0);
if( stdenv == (MLEnvironment)0) goto R0;

if( !stdyielder)
stdyielder = MLCreateYieldFunction( stdenv,
NewMLYielderProc( MLDefaultYielder), 0);
if( !stdhandler)
stdhandler = MLCreateMessageHandler( stdenv,
NewMLHandlerProc( MLDefaultHandler), 0);


mlp = commandline
? MLOpenString( stdenv, commandline, &err)
: MLOpenArgv( stdenv, argv, argv_end, &err);
if( mlp == (MLINK)0){
MLAlert( stdenv, MLErrorString( stdenv, err));
goto R1;
}

if( MLIconWindow){
char textbuf[64];
int len;
len = GetWindowText(MLIconWindow, textbuf, sizeof(textbuf)-2);
strcat( textbuf + len, ''('');
_fstrncpy( textbuf + len + 1, MLName(mlp), sizeof(textbuf) - len - 3);
textbuf[sizeof(textbuf) - 2] = '\0';
strcat( textbuf, '')'');
SetWindowText( MLIconWindow, textbuf);
}

if( MLInstance){
if( stdyielder) MLSetYieldFunction( mlp, stdyielder);
if( stdhandler) MLSetMessageHandler( mlp, stdhandler);
}

if( MLInstall( mlp))
while( MLAnswer( mlp) == RESUMEPKT){
if( ! refuse_to_be_a_frontend( mlp)) break;
}

MLClose( mlp);
R1: MLDeinitialize( stdenv);
stdenv = (MLEnvironment)0;
R0: return !MLDone;
} /* _MLMain */


int MLMainString( charp_ct commandline)
{
return _MLMain( (charpp_ct)0, (charpp_ct)0, commandline);
}

int MLMainArgv( char** argv, char** argv_end) /* note not FAR pointers */
{
static char FAR * far_argv[128];
int count = 0;

while(argv < argv_end)
far_argv[count++] = *argv++;

return _MLMain( far_argv, far_argv + count, (charp_ct)0);

}

int MLMain( int argc, charpp_ct argv)
{
return _MLMain( argv, argv + argc, (charp_ct)0);
}



end stringtm.cpp **************************************************

--
Dave Richardson
University of Maryland
Department of Mechanical Engineering
Center for Environmental Energy Engineering
(301) 405-8726
dhr@glue.umd.edu


URL: ,
Help | Reply To Topic