Skip to content

Instantly share code, notes, and snippets.

@khaotik
Last active September 5, 2018 07:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khaotik/bbc915e53223ff68cef0d06302b6b110 to your computer and use it in GitHub Desktop.
Save khaotik/bbc915e53223ff68cef0d06302b6b110 to your computer and use it in GitHub Desktop.
Receive packed array via WSTP
#include <stdlib.h>
#include <vector>
#include <string>
#include "wstp.h"
using namespace std;
int main() {
int err;
auto env_p = WSInitialize((void*)0);
auto link_p = WSOpenString(env_p, "-linkname someLink -linkmode connect", &err);
if (err != WSEOK) { /* error ... */ }
auto token = WSGetType(link_p);
auto raw_token = WSGetRawType(link_p);
auto temp_link_p = WSLoopbackOpen(env_p, &err);
if (err != WSEOK) { /* error ... */ }
array_meterp am;
long depth;
vector<int> shape;
vector<string> heads;
size_t total_size = 1;
const char *head_p;
int argcount;
int elem_token;
auto mark = WSCreateMark(link_p);
do {
WSGetFunction(link_p, &head_p, &argcount);
total_size *= argcount;
shape.push_back(argcount);
heads.push_back(string(head_p));
WSReleaseSymbol(link_p, head_p);
elem_token = WSGetRawType(link_p);
} while (elem_token == WSTKFUNC);
switch (elem_token) {
case WSTK_CDOUBLE:
total_size *= sizeof(double);
break;
case WSTK_CFLOAT:
total_size *= sizeof(float);
break;
default:
/* error ... */
break;
}
WSSeekToMark(link_p, mark, 0);
WSDestroyMark(link_p, mark);
void *array_data;
long *received_dims;
char **received_heads;
long received_depth;
WSGetBinaryNumberArray(
link_p, &array_data, &received_dims, &received_heads, &received_depth, elem_token);
/* do stuff with array */
// there is a int/long mismatch on received_dims, I don't understand why
WSReleaseBinaryNumberArray(
link_p, array_data, (int*)received_dims, received_heads, total_size, elem_token);
return 0;
}
#include <stdlib.h>
#include <vector>
#include <string>
#include "wstp.h"
using namespace std;
int main() {
int err;
auto env_p = WSInitialize((void*)0);
auto link_p = WSOpenString(env_p, "-linkname someLink -linkmode connect", &err);
if (err != WSEOK) { /* error ... */ }
auto token = WSGetType(link_p);
auto raw_token = WSGetRawType(link_p);
auto temp_link_p = WSLoopbackOpen(env_p, &err);
if (err != WSEOK) { /* error ... */ }
array_meterp am;
long depth;
mlapi__token leaf_token; // this token seems unused
if (!WSGetArrayTypeWithDepthAndLeafType(link_p, temp_link_p, &am, &depth, &leaf_token)) {
/* error ... */
}
size_t total_size = 1;
const char *head_p;
int argcount;
vector<int> shape;
vector<string> heads;
for (int i=0; i<depth; ++i) {
WSGetFunction(temp_link_p, &head_p, &argcount);
total_size *= argcount;
shape.push_back(argcount);
heads.push_back(string(head_p));
WSReleaseSymbol(link_p, head_p);
}
auto elem_token = WSGetRawType(link_p);
switch (elem_token) {
case WSTK_CDOUBLE:
total_size *= sizeof(double);
break;
case WSTK_CFLOAT:
total_size *= sizeof(float);
break;
default:
/* error ... */
break;
}
void *array_data = malloc(total_size);
WSGetBinaryNumberArrayData(link_p, am, array_data, total_size, elem_token);
WSReleaseGetArrayState(link_p, temp_link_p, am);
WSClose(temp_link_p);
/* do stuff with array */
free(array_data);
return 0;
}
(* run this first, then compiled c++ program *)
link = LinkCreate["someLink", LinkMode->Listen];
LinkWrite[link, RandomReal[1., {4,4}]];
InputString["Done"];
LinkClose[link];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment