Is there the ways to forward output from XCode to Processing? - xcode

I'm trying out to forward output stream from XCode (v12.4) to Processing (https://processing.org/).
My goal is: To draw a simple object in Processing according to my XCode project data.
I need to see value of my variable in the Processing.
int main(int argc, const char * argv[]) {
// insert code here...
for (int i=0; i<10; i++)
std::cout << "How to send value of i to the Processing!\n";
return 0;
}

Finally I found the way. Hope it help someone. Share it.
Xcode app ->(127.0.0.1:UDP)-> Processing sketch
Source Links:
Sending string over UDP in C++
https://discourse.processing.org/t/receive-udp-packets/19832
Xcode app (C++):
int main(int argc, char const *argv[])
{
std::string hostname{"127.0.0.1"};
uint16_t port = 6000;
int sock = ::socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in destination;
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
destination.sin_addr.s_addr = inet_addr(hostname.c_str());
std::string msg = "Hello world!";
for(int i=0; i<5; i++){
long n_bytes = ::sendto(sock, msg.c_str(), msg.length(), 0, reinterpret_cast<sockaddr*>(&destination), sizeof(destination));
std::cout << n_bytes << " bytes sent" << std::endl;
}
::close(sock);
return 0;
}
Processing code:
import java.net.*;
import java.io.*;
import java.util.Arrays;
DatagramSocket socket;
DatagramPacket packet;
byte[] buf = new byte[12]; //Set your buffer size as desired
void setup() {
try {
socket = new DatagramSocket(6000); // Set your port here
}
catch (Exception e) {
e.printStackTrace();
println(e.getMessage());
}
}
void draw() {
try {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
//Received as bytes:
println(Arrays.toString(buf));
//If you wish to receive as String:
String received = new String(packet.getData(), 0, packet.getLength());
println(received);
}
catch (IOException e) {
e.printStackTrace();
println(e.getMessage());
}
}

The assumption is you're using c++ in Xcode (and not Objective-C, nor Swift).
Every processing sketch inherits the args property (very similar to main's const char * argv[] in c++ program). You can make use of that to initialise a Processing sketch with options from c++.
You could have something like:
int main(int argc, const char * argv[]) {
system("/path/to/processing-java --sketch-path=/path/to/your/processing/sketch/folder --run 0,1,2,3,4,5,6,7,8,9");
return 0;
}
(This is oversimplified, you'd have your for loop accumulate ints into a string with a separator character, maybe setup variables for paths to processing-java and the processing sketch)
To clarify, processing-java is a command line utility that ships with Processing. (You can find it in inside the Processing.app folder (via show contents), alongside the processing executable and install it via Tools menu inside Processing). It allows you to easily run a sketch from the command line. Alternatively, you can export an application, however if you're prototyping, the processing-java option might be more practical.
In Processing you'd check if the sketch was launched with arguments, and if so, parse those arguments.
void setup(){
if(args != null){
printArray(args);
}
}
You can use split() to split 0,1,2,3,4,5,6,7,8,9 into individual numbers that can be parsed (via int() for example).
If you have more complex data, you can consider formatting your c++ output as JSON, then using parseJSONObject() / parseJSONArray().
(If you don't want to split individual values, you can just use spaces with command line arguments: /path/to/processing-java --sketch-path=/path/to/your/processing/sketch/folder --run 0 1 2 3 4 5 6 7 8 9. If you want to send a JSON formatted string from c++, be aware you may need to escape " (e.g. system("/path/to/processing-java --sketch-path=/path/to/your/processing/sketch/folder --run {\"myCppData\":[0,1,2]}");)
This would work if you need to launch the processing sketch once and initialise with values from your c++ program at startup. Outside of the scope of your question, if you need to continously send values from c++ to Processing, you can look at opening a local socket connection (TCP or UDP) to estabish communication between the two programs. One easy to use protocol is OSC (via UDP). You can use oscpack in raw c++ and oscp5 in Processing. (Optionally, depending on your setup you can consider openFrameworks which (already has oscpack integrated as ofxOsc and ships with send/receive examples): its ofApp is similar Processing's PApplet (e.g. setup()/draw()/mousePressed(), etc.)

Related

Protobuf exception when allocating memory for string in dll

I am using protobuf 3 to serialize a simple message.
I get a bad alloc when i set a string value for one of the memebers of my protobuf message like so.
std::string a("eeee");
hello_in.set_name(a);
The bad alloc exception happens in the libprotobuf.dll in this function...
void CreateInstance(Arena* arena, const ::std::string* initial_value) {
GOOGLE_DCHECK(initial_value != NULL);
// uses "new ::std::string" when arena is nullptr
ptr_ = Arena::Create< ::std::string>(arena, *initial_value);
}
But i think the real problem is that initial_value has been corrupted somehow and has a size of [size] = 3435973836.
Not sure how this is being corrupted. CreateInstance does get called a few times prior to this but its the first time it is called from main.cpp. Which leads me to believe that it has something to do with dll's and ownership of memeory.
Using any of the other set_name functions also cause a bad alloc exception.
Setting the bool or int in the message works fine.
Here is the message and the main.cpp. I didnt include the hello.pb.h/pb.cc as they are quite big but can if it helps.
// See README.txt for information and build instructions.
//
// Note: START and END tags are used in comments to define sections used in
// tutorials. They are not part of the syntax for Protocol Buffers.
//
// To get an in-depth walkthrough of this file and the related examples, see:
// https://developers.google.com/protocol-buffers/docs/tutorials
// [START declaration]
syntax = "proto3";
package commands;
import "google/protobuf/timestamp.proto";
// [END declaration]
// [START messages]
message Hello {
string name = 1;
int32 id = 2; // Unique ID number for this person.
bool on = 3;
google.protobuf.Timestamp last_updated = 4;
}
// [END messages]
#include "hello.pb.h"
// stl
#include <fstream>
#include <iostream>
int main()
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
commands::Hello hello_in;
hello_in.set_id(2);
std::string a("eeee");
hello_in.set_name(a);
hello_in.set_on(false);
{
// Write the new address book back to disk.
std::fstream output("hello.txt", std::ios::out | std::ios::trunc | std::ios::binary);
if (!hello_in.SerializeToOstream(&output)) {
std::cerr << "Failed to write address book." << std::endl;
return -1;
}
}
commands::Hello hello_out;
{
// Read the existing address book.
std::fstream input("hello.txt", std::ios::in | std::ios::binary);
if (!input) {
std::cout << "hello.txt" << ": File not found. Creating a new file." << std::endl;
}
else if (!hello_out.ParseFromIstream(&input)) {
std::cerr << "Failed to parse address book." << std::endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
I have observed same behavior (Visual Studio 2019 C++ project). The solution which helped me: libprotobuf.lib and libprotobuf.dll were replaced in debug/x86 mode by its debug version, libprotobufd.lib and libprotobufd.dll.

How to write data to InfluxDB with ESP8266 / NodeMCU over Internet & HTTPS?

I want to securely send data to my InfluxDB over the Internet using a NodeMCU MCU and a self signed cert.
I found this library that seems to accomplish exactly this but get compile errors, more below -> https://medium.com/#teebr/iot-with-an-esp32-influxdb-and-grafana-54abc9575fb2
This library seems to only use HTTP -> Am i mistaken?
https://www.arduinolibraries.info/libraries/esp8266-influxdb
Using the example from the 1st library above from TEEBR, i get this error compiling - Any suggestions on how to fix? Will this run on my NodeMCU?
Thanks
C:\Users\Jason\Documents\Arduino\libraries\Influx-Arduino-master\InfluxArduino.cpp:1:24: fatal error: HTTPClient.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
My code
//https://medium.com/#teebr/iot-with-an-esp32-influxdb-and-grafana-54abc9575fb2
#include <WiFi.h>
#include "InfluxArduino.hpp"
#include "InfluxCert.hpp"
InfluxArduino influx;
//connection/ database stuff that needs configuring
char WIFI_NAME[] = "ssid";
const char WIFI_PASS[] = "password!";
const char INFLUX_DATABASE[] = "db_name";
const char INFLUX_IP[] = "10.10.101.101";
const char INFLUX_USER[] = "db_name"; //username if authorization is enabled.
const char INFLUX_PASS[] = "Password"; //password for if authorization is enabled.
const char INFLUX_MEASUREMENT[] = "FromESP8266"; //measurement name for the database. (in practice, you can use several, this example just uses the one)
unsigned long DELAY_TIME_US = 5 * 1000 * 1000; //how frequently to send data, in microseconds
unsigned long count = 0; //a variable that we gradually increase in the loop
void setup()
{
Serial.begin(115200);
WiFi.begin(WIFI_NAME, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
influx.configure(INFLUX_DATABASE,INFLUX_IP); //third argument (port number) defaults to 8086
influx.authorize(INFLUX_USER,INFLUX_PASS); //if you have set the Influxdb .conf variable auth-enabled to true, uncomment this
influx.addCertificate(ROOT_CERT); //uncomment if you have generated a CA cert and copied it into InfluxCert.hpp
Serial.print("Using HTTPS: ");
Serial.println(influx.isSecure()); //will be true if you've added the InfluxCert.hpp file.
}
void loop()
{
unsigned long startTime = micros(); //used for timing when to send data next.
//update our field variables
float dummy = ((float)random(0, 1000)) / 1000.0;
count++;
//write our variables.
char tags[32];
char fields[32];
sprintf(tags,"new_tag=Yes"); //write a tag called new_tag
sprintf(fields,"count=%d,random_var=%0.3f",count,dummy); //write two fields: count and random_var
bool writeSuccessful = influx.write(INFLUX_MEASUREMENT,tags,fields);
if(!writeSuccessful)
{
Serial.print("error: ");
Serial.println(influx.getResponse());
}
while ((micros() - startTime) < DELAY_TIME_US)
{
//wait until it's time for next reading. Consider using a low power mode if this will be a while.
}
}
Long time reader, first time poster - Thanks for all the help in the past!

Using Thrift for IPC-Communication via shared Memory

I couldn't find a sufficient example on how to use apache thrift for ipc-communication via shared memory. My goal is to serialize an exisiting class with help of thrift, then send via shared memory to a different process where i deserialize it again with help of thrift. Right now i'm using TMemoryBuffer and TBinaryProtocol to serialize the data. Although this works, I have no idea on how to write it to shared memory.
Here is my code so far:
#include "test_types.h"
#include "test_constants.h"
#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/transport/TBufferTransports.h"
int main(int argc, char** argv)
{
int shID;
char* myPtr;
Person* dieter = new Person("Dieter", "Neuer");
//Person* johann = new Person("Johann", "Liebert");
//Car* ford = new Car("KLENW", 4, 4);
PersonThrift dieterThrift;
dieterThrift.nachName = dieter->getNachname();
dieterThrift.vorName = dieter->getVorname();
boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> transport(new apache::thrift::transport::TMemoryBuffer);
boost::shared_ptr<apache::thrift::protocol::TBinaryProtocol> protocol(new apache::thrift::protocol::TBinaryProtocol(transport));
test thriftTest;
thriftTest.personSet.insert(dieterThrift);
u_int32_t size = thriftTest.write(protocol.get());
std::cout << transport.get()->getBufferAsString();
shID = shmget(1000, 100, IPC_CREAT | 0666);
if (shID >= 0)
{
myPtr = (char*)shmat(shID, 0, 0);
if (myPtr==(char *)-1)
{
perror("shmat");
}
else
{
//myPtr = protocol.get();
}
}
getchar();
shmdt(myPtr);
}
The main problem is the part
//myPtr = protocol.get();
How do I use thrift so that I can write my deserialized data into myPtr (and thus into shared memory). I guess TMemoryBuffer might already be a bad idea. As you may see, I'm not really experienced with this.
Kind regards and thanks in advance
Michael
After reading the question again and having a closer look at the code ... you were almost there. The mistake you made is to look at the protocol, which gives you no data. Instead, you have to ask the transport, as you already did with
std::cout << transport.get()->getBufferAsString();
The way to get the raw data is quite similar, just use getBuffer(&pbuf, &sz); instead. Using this, we get something like this:
// query buffer pointer and data size
uint8_t* pbuf;
uint32_t sz;
transport.get()->getBuffer(&pbuf, &sz);
// alloc shmem blöock of adequate size
shID = shmget(1000, sz, IPC_CREAT | 0666);
if (shID >= 0)
{
myPtr = (char*)shmat(shID, 0, 0);
if (myPtr==(char *)-1)
{
perror("shmat");
}
else
{
// copy serialized data into shared memory
memcpy( myPtr, pbuf, sz);
}
}
Since shmget() may give you a larger block than requested, it seems to be a good idea to additionally use the framed transport, which automatically carries the real data size in the serialized data. Some sample code for the latter can be found in the Test Client or server code.

WinAPI C++ client detect write on anonymous pipe before reading

I am writing a C++ (Windows) client console application which reads from an anonymous pipe on STDIN. I would like to be able to use my program as follows:
echo input text here | my_app.exe
and do something in the app with the text that is piped in
OR
my_app.exe
and then use some default text inside of the app instead of the input from the pipe.
I currently have code that successfully reads from the pipe on STDIN given the first situation:
#include <Windows.h>
#include <iostream>
#include <string>
#define BUFSIZE 4096
int main(int argc, const char *argv[]) {
char char_buffer[BUFSIZE];
DWORD bytes_read;
HANDLE stdin_handle;
BOOL continue_reading;
unsigned int required_size;
bool read_successful = true;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
if (stdin_handle == INVALID_HANDLE_VALUE) {
std::cout << "Error: invalid handle value!\n\n";
} else {
continue_reading = true;
while (continue_reading) {
continue_reading = ReadFile(stdin_handle, char_buffer, BUFSIZE,
&bytes_read, NULL);
if (continue_reading) {
if (bytes_read != 0) {
// Output what we have read so far
for (unsigned int i = 0; i < bytes_read; i++) {
std::cout << char_buffer[i];
}
} else {
continue_reading = false;
}
}
}
}
return 0;
}
I know that my only option with anonymous pipes is to do a blocking read with ReadFile. If I understand correctly, in regard to how I am invoking it, ReadFile will continue to read from the buffer on STDIN until it detects an end of write operation on the other end of the pipe (perhapse reads some sort of "end of write" token??). I would like to know if there is some sort of "beginning write" token that will be in the buffer if something is being piped in which I can check on STDIN BEFORE I call ReadFile. If this were the case I could just skip calling ReadFile and use some default text.
If there is not a way to do this, I can always pass in a command line argument that denotes that I should not check the pipe and just use the default text (or the other way around), but I would much prefer to do it the way that I specified.
Look at PeekNamedPipe(). Despite its name, it works for both named and anonymous pipes.
int main(int argc, const char *argv[])
{
char char_buffer[BUFSIZE];
DWORD bytes_read;
DWORD bytes_avail;
DWORD dw;
HANDLE stdin_handle;
bool is_pipe;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(stdin_handle, &dw);
if (stdin_handle == INVALID_HANDLE_VALUE) {
std::cout << "Error: invalid handle value!\n\n";
} else {
while (1) {
if (is_pipe) {
if (PeekNamedPipe(stdin_handle, NULL, 0, NULL, &bytes_avail, NULL)) {
if (bytes_avail == 0) {
Sleep(100);
continue;
}
}
}
if (!ReadFile(stdin_handle, char_buffer, min(bytes_avail, BUFSIZE), &bytes_read, NULL)) {
break;
}
if (bytes_read == 0) {
break;
}
// Output what we have read so far
for (unsigned int i = 0; i < bytes_read; i++) {
std::cout << char_buffer[i];
}
}
}
return 0;
}
It looks like what you're really trying to do here is to determine whether you've got console input (where you use default value) vs pipe input (where you use input from the pipe).
Suggest testing that directly instead of trying to check if there's input ready: the catch with trying to sniff whether there's data in the pipe is that if the source app is slow in generating output, your app might make an incorrect assumption just because there isn't input yet available. (It might also be possible that, due to typeahead, there's a user could have typed in characters that area ready to be read from console STDIN before your app gets around to checking if input is available.)
Also, keep in mind that it might be useful to allow your app to be used with file redirection, not just pipes - eg:
myapp.exe < some_input_file
The classic way to do this "interactive mode, vs used with redirected input" test on unix is using isatty(); and luckily there's an equivalent in the Windows CRT - see function _isatty(); or use GetFileType() checking for FILE_TYPE_CHAR on GetStdHandle(STD_INPUT_HANDLE) - or use say GetConsoleMode as Remy does, which will only succeed on a real console handle.
This also works without overlapped I/O while using a second thread, that does the synchronous ReadFile-call. Then the main thread waits an arbitrary amount of time and acts like above...
Hope this helps...

URL rewrite on G-WAN for .JPG

I am testing G-WAN server and I'd like using rewrite rules.
With apache the rule is :
RewriteRule ^(.+)-(.+)-(.+)-1.jpg$ imagesproduitnew/$3/$2.jpg [L]
I am trying to do it by handlers JPG, but I have lot of difficulties.
Has anybody already done something like that ?
My handlers is called url_wr.c in the path /0.0.0.0_80/#0.0.0.0/handlers
Here is the script
int init(char *argv[], int argc);
int main(int argc, char *argv[])
{
const long state = (long)argv[0];
if(state == HDL_AFTER_READ)
{
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/blog", "/?blog");
}
return 255; // execute next connection step
}
int clean(char *argv[], int argc);
In gwan.log, it is not writen loaded url_wr.c
If I put printf in each function, it doesn't work.
The servlet bloc.c works well.
I also tried tu put the code in handlers/main.c and in the root of gwan directory.
I have only a error.log file for the site which says just error404 without any details of the handlers.
Thanks by advance for your support
You must use a G-WAN connection handler, either to use:
a plain-rewrite: one example is given at the end of the developers page,
OR,
a regex library (libc provides regex calls) if you target a more general rewrite scheme. Here is an example in C and the explanations are there, courtesy of "Regular Expressions in C" from the "Linux Gazette".
This could also be made rom a servlet, but then you would have to trigger a redirection (unless the resource was explicitely placed into a cache). If this is acceptable, then v3.10+ will let you do it in C#, PHP, Python, etc.
UPDATE following the code published in the question:
Your init() call is empty so main() is never called. You should do this instead:
// ----------------------------------------------------------------------------
// init() will initialize your data structures, load your files, etc.
// ----------------------------------------------------------------------------
// init() should return -1 if failure (to allocate memory for example)
int init(int argc, char *argv[])
{
// define which handler states we want to be notified in main():
// enum HANDLER_ACT {
// HDL_INIT = 0,
// HDL_AFTER_ACCEPT, // just after accept (only client IP address setup)
// HDL_AFTER_READ, // each time a read was done until HTTP request OK
// HDL_BEFORE_PARSE, // HTTP verb/URI validated but HTTP headers are not
// HDL_AFTER_PARSE, // HTTP headers validated, ready to build reply
// HDL_BEFORE_WRITE, // after a reply was built, but before it is sent
// HDL_HTTP_ERRORS, // when G-WAN is going to reply with an HTTP error
// HDL_CLEANUP };
//
u32 *states = (u32*)get_env(argv, US_HANDLER_STATES);
*states = 1 << HDL_AFTER_READ; // we assume "GET /hello" sent in one shot
puts("init()");
return 0;
}
Also, make sure that connection handlers are named main.c. In contrast, content handlers carry the name of the targeted file extension (gif.c, html.c, etc).

Resources