I downloaded the SDK from https://developer.leapmotion.com/sdk-leap-motion-controller and tried running the code under samples. It works for java and javascript but doesn't work for cpp and python.
The controller is connected and working. And the service 'leapd' is running in the background.
Any idea what might be the cause?
I am on macOS (Big Sur 11.1)
EDIT:
.
├── Makefile
├── include
│ ├── Leap.h
│ └── LeapMath.h
├── lib
│ └── libLeap.dylib
├── main
└── main.cpp
/******************************************************************************\
* Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. *
* Leap Motion proprietary and confidential. Not for distribution. *
* Use subject to the terms of the Leap Motion SDK Agreement available at *
* https://developer.leapmotion.com/sdk_agreement, or another agreement *
* between Leap Motion and you, your company or other organization. *
\******************************************************************************/
#include <iostream>
#include <cstring>
#include "Leap.h"
using namespace Leap;
class SampleListener : public Listener {
public:
virtual void onInit(const Controller&);
virtual void onConnect(const Controller&);
virtual void onDisconnect(const Controller&);
virtual void onExit(const Controller&);
virtual void onFrame(const Controller&);
virtual void onFocusGained(const Controller&);
virtual void onFocusLost(const Controller&);
virtual void onDeviceChange(const Controller&);
virtual void onServiceConnect(const Controller&);
virtual void onServiceDisconnect(const Controller&);
private:
};
const std::string fingerNames[] = {"Thumb", "Index", "Middle", "Ring", "Pinky"};
const std::string boneNames[] = {"Metacarpal", "Proximal", "Middle", "Distal"};
const std::string stateNames[] = {"STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END"};
void SampleListener::onInit(const Controller& controller) {
std::cout << "Initialized" << std::endl;
}
void SampleListener::onConnect(const Controller& controller) {
std::cout << "Connected" << std::endl;
controller.enableGesture(Gesture::TYPE_CIRCLE);
controller.enableGesture(Gesture::TYPE_KEY_TAP);
controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
controller.enableGesture(Gesture::TYPE_SWIPE);
}
void SampleListener::onDisconnect(const Controller& controller) {
// Note: not dispatched when running in a debugger.
std::cout << "Disconnected" << std::endl;
}
void SampleListener::onExit(const Controller& controller) {
std::cout << "Exited" << std::endl;
}
void SampleListener::onFrame(const Controller& controller) {
// Get the most recent frame and report some basic information
const Frame frame = controller.frame();
std::cout << "Frame id: " << frame.id()
<< ", timestamp: " << frame.timestamp()
<< ", hands: " << frame.hands().count()
<< ", extended fingers: " << frame.fingers().extended().count()
<< ", tools: " << frame.tools().count()
<< ", gestures: " << frame.gestures().count() << std::endl;
HandList hands = frame.hands();
for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) {
// Get the first hand
const Hand hand = *hl;
std::string handType = hand.isLeft() ? "Left hand" : "Right hand";
std::cout << std::string(2, ' ') << handType << ", id: " << hand.id()
<< ", palm position: " << hand.palmPosition() << std::endl;
// Get the hand's normal vector and direction
const Vector normal = hand.palmNormal();
const Vector direction = hand.direction();
// Calculate the hand's pitch, roll, and yaw angles
std::cout << std::string(2, ' ') << "pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, "
<< "roll: " << normal.roll() * RAD_TO_DEG << " degrees, "
<< "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl;
// Get the Arm bone
Arm arm = hand.arm();
std::cout << std::string(2, ' ') << "Arm direction: " << arm.direction()
<< " wrist position: " << arm.wristPosition()
<< " elbow position: " << arm.elbowPosition() << std::endl;
// Get fingers
const FingerList fingers = hand.fingers();
for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl) {
const Finger finger = *fl;
std::cout << std::string(4, ' ') << fingerNames[finger.type()]
<< " finger, id: " << finger.id()
<< ", length: " << finger.length()
<< "mm, width: " << finger.width() << std::endl;
// Get finger bones
for (int b = 0; b < 4; ++b) {
Bone::Type boneType = static_cast<Bone::Type>(b);
Bone bone = finger.bone(boneType);
std::cout << std::string(6, ' ') << boneNames[boneType]
<< " bone, start: " << bone.prevJoint()
<< ", end: " << bone.nextJoint()
<< ", direction: " << bone.direction() << std::endl;
}
}
}
// Get tools
const ToolList tools = frame.tools();
for (ToolList::const_iterator tl = tools.begin(); tl != tools.end(); ++tl) {
const Tool tool = *tl;
std::cout << std::string(2, ' ') << "Tool, id: " << tool.id()
<< ", position: " << tool.tipPosition()
<< ", direction: " << tool.direction() << std::endl;
}
// Get gestures
const GestureList gestures = frame.gestures();
for (int g = 0; g < gestures.count(); ++g) {
Gesture gesture = gestures[g];
switch (gesture.type()) {
case Gesture::TYPE_CIRCLE:
{
CircleGesture circle = gesture;
std::string clockwiseness;
if (circle.pointable().direction().angleTo(circle.normal()) <= PI/2) {
clockwiseness = "clockwise";
} else {
clockwiseness = "counterclockwise";
}
// Calculate angle swept since last frame
float sweptAngle = 0;
if (circle.state() != Gesture::STATE_START) {
CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id()));
sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI;
}
std::cout << std::string(2, ' ')
<< "Circle id: " << gesture.id()
<< ", state: " << stateNames[gesture.state()]
<< ", progress: " << circle.progress()
<< ", radius: " << circle.radius()
<< ", angle " << sweptAngle * RAD_TO_DEG
<< ", " << clockwiseness << std::endl;
break;
}
case Gesture::TYPE_SWIPE:
{
SwipeGesture swipe = gesture;
std::cout << std::string(2, ' ')
<< "Swipe id: " << gesture.id()
<< ", state: " << stateNames[gesture.state()]
<< ", direction: " << swipe.direction()
<< ", speed: " << swipe.speed() << std::endl;
break;
}
case Gesture::TYPE_KEY_TAP:
{
KeyTapGesture tap = gesture;
std::cout << std::string(2, ' ')
<< "Key Tap id: " << gesture.id()
<< ", state: " << stateNames[gesture.state()]
<< ", position: " << tap.position()
<< ", direction: " << tap.direction()<< std::endl;
break;
}
case Gesture::TYPE_SCREEN_TAP:
{
ScreenTapGesture screentap = gesture;
std::cout << std::string(2, ' ')
<< "Screen Tap id: " << gesture.id()
<< ", state: " << stateNames[gesture.state()]
<< ", position: " << screentap.position()
<< ", direction: " << screentap.direction()<< std::endl;
break;
}
default:
std::cout << std::string(2, ' ') << "Unknown gesture type." << std::endl;
break;
}
}
if (!frame.hands().isEmpty() || !gestures.isEmpty()) {
std::cout << std::endl;
}
}
void SampleListener::onFocusGained(const Controller& controller) {
std::cout << "Focus Gained" << std::endl;
}
void SampleListener::onFocusLost(const Controller& controller) {
std::cout << "Focus Lost" << std::endl;
}
void SampleListener::onDeviceChange(const Controller& controller) {
std::cout << "Device Changed" << std::endl;
const DeviceList devices = controller.devices();
for (int i = 0; i < devices.count(); ++i) {
std::cout << "id: " << devices[i].toString() << std::endl;
std::cout << " isStreaming: " << (devices[i].isStreaming() ? "true" : "false") << std::endl;
}
}
void SampleListener::onServiceConnect(const Controller& controller) {
std::cout << "Service Connected" << std::endl;
}
void SampleListener::onServiceDisconnect(const Controller& controller) {
std::cout << "Service Disconnected" << std::endl;
}
int main(int argc, char** argv) {
// Create a sample listener and controller
SampleListener listener;
Controller controller;
// Have the sample listener receive events from the controller
controller.addListener(listener);
if (argc > 1 && strcmp(argv[1], "--bg") == 0)
controller.setPolicy(Leap::Controller::POLICY_BACKGROUND_FRAMES);
// Keep this process running until Enter is pressed
std::cout << "Press Enter to quit..." << std::endl;
std::cin.get();
// Remove the sample listener when done
controller.removeListener(listener);
return 0;
}
LEAP_LIBRARY := ./lib/libLeap.dylib
main: main.cpp
$(CXX) -Wall -g -I ./include main.cpp -o main $(LEAP_LIBRARY);
install_name_tool -change #loader_path/libLeap.dylib ./lib/libLeap.dylib main
clean:
rm -rf main main.dSYM
$ otool -L lib/libLeap.dylib
lib/libLeap.dylib:
#loader_path/libLeap.dylib (compatibility version 0.7.0, current version 2.3.1)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1265.21.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 48.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
Related
I use tensorflow C++ API.I train model on GPU and execute this code(for predict)
#include<iostream>
using namespace tensorflow;
tensorflow::Tensor loadImage(tensorflow::string fname){
tensorflow::int32 width = 224;
tensorflow::int32 height = 224;
tensorflow::int32 nData = 1;
tensorflow::int32 nVec = width*height;
tensorflow::int32 channels = 3;
auto tensor = tensorflow::Tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, height, width, channels}));
auto mat = tensor.tensor<float, 4>();
std::ifstream fin(fname, std::ios_base::in | std::ios_base::binary);
assert(!fin.fail());
boost::iostreams::filtering_istream s;
s.push(fin);
char c;
for(int i=0;i<nData;i++){
for(int h=0;h<height;h++){
for(int w=0;w<width;w++){
for(int j=0;j<channels;j++){
s.get(c);
mat(i, h, w, j) = static_cast<float>(static_cast<uint8_t>(c)) / 255.0;
}
}
}
}std::cout << "Image Loaded" << std::endl;
return tensor;
}
int main(int argc, char* argv[]) {
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
}
GraphDef graph_def;
status = ReadBinaryProto(Env::Default(), "graph.pb", &graph_def);
if (!status.ok()) {
std::cout << "Status Not OK" << std::endl;
std::cout << status.ToString() << "\n";
return 1;
}
else{
std::cout << "Graph Loaded" << std::endl;
}
status = session->Create(graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
}
else{
std::cout << "Create End" << std::endl;
}
std::string fname = "test.jpg";
tensorflow::Tensor img = loadImage(fname);
std::vector<std::pair<tensorflow::string, tensorflow::Tensor>> inputs = {{"img0001", img }};
std::vector<tensorflow::Tensor> outputs;
std::cout << "Start Run" << std::endl;
status = session->Run(inputs, {"output_node0"}, {}, &outputs);
std::cout << "End Run" << std::endl;
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 1;
}
std::cout << outputs[0].DebugString() << "\n";
std::cout << output_c() << "\n"; // 30
session->Close();
return 0;
}
But, I got unknown error like this.
Invalid argument: Tensor img0001:0, specified in either feed_devices or fetch_devices was not found in the Graph
This error occured this code.
session->Run(inputs, {"output_node0"}, {}, &outputs);
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/common_runtime/graph_execution_state.cc
At this site explain this error occurs when node name is not equal.
I create model by keras, not tensorflow.
So, I translate model from keras to tensorflow by this code.
https://github.com/icchi-h/keras_to_tensorflow/blob/master/keras_to_tensorflow.py
I guess it has a connection with training on GPU.
https://github.com/tensorflow/tensorflow/issues/5902
But, I can't get corroboration about this.
Please teach me the solution of this problem.
I was provided with a CMAKE-File for a c++ Code and want to wrap its function into python. Whenever I try to import the function it's giving me an Import Error:
dynamic module does not define init function (init_main)
This is the c++ code:
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <Memory/Interface.hpp>
#include <Memory/Subscription.hpp>
using namespace memory::interface;
using namespace memory;
MemoryPtr mMem;
Subscription *s;
std::string write_document;
void subscriber_callback(const Event &event) {
std::cout << "Received an event:" << std::endl;
switch (event.getType()) {
case Event::INSERT:
std::cout << "Insert event with document ID = " << event.getID() << std::endl;
break;
case Event::REMOVE:
std::cout << "Remove event with document ID = " << event.getID() << std::endl;
break;
case Event::QUERY:
std::cout << "Query event with document ID = " << event.getID() << std::endl;
break;
case Event::REPLACE:
std::cout << "Replace event with document ID = " << event.getID() << std::endl;
break;
case Event::ALL:
std::cout << "Generic event with document ID = " << event.getID() << std::endl;
break;
default: std::cout << "Unknown event type." << std::endl;
}
std::cout << "Contained document is: " << event.getDocument() << std::endl;
}
extern "C" int main(int argc, char *argv[]) {
// validate app arguments
if(argc < 3) {
std::cerr << "Usage : " << argv[0] << " <xcf:ShortTerm> <XPATH-trigger>" << std::endl;
return 1;
}
try {
// instantiate the memory interface
mMem = MemoryInterface::getInstance(argv[1]);
std::cout << "Memory interface initialized" << std::endl;
// create the trigger
std::string xpath(argv[2]);
// create a subscriber to a specific xpath event
s = new Subscription(
Condition(Event::INSERT, xpath),
TriggeredAction(boost::bind(&subscriber_callback, _1))
);
mMem->subscribe (*s);
std::cout << "Memory interface subscriber initialized" << std::endl;
// insert command/text to memory
write_document = "<command><stop /></command>";
mMem->insert(write_document);
std::cout << "Written to Memory interface" << std::endl;
// wait for key press
std::string end;
std::cin >> end;
}
catch (const MemoryInterfaceException& e) {
std::cerr << "MemoryInterfaceException: " << e.what() << std::endl;
return 1;
}
catch(std::exception &e) {
std::cerr << std::endl << "Could not initialize memory::interface. Reason:"
<< std::endl << e.what() << std::endl;
return 1;
}
return 0;
}
This is the CMAKE File to which I added the last SWIG part:
cmake_minimum_required(VERSION 3.0.2)
project(xcf_minimal_readwrite)
find_package(PkgConfig)
IF(PKG_CONFIG_FOUND)
message(STATUS "found pkgconfig")
SET(MODULE "Memory")
IF(Memory_FIND_REQUIRED)
SET(Memory_REQUIRED "REQUIRED")
ENDIF()
PKG_CHECK_MODULES(Memory ${Memory_REQUIRED} ${MODULE})
FIND_LIBRARY(Memory_LIBRARY
NAMES ${Memory_LIBRARIES}
HINTS ${Memory_LIBRARY_DIRS}
)
SET(Memory_LIBRARIES ${Memory_LIBRARY})
SET(MODULE "xmltio")
IF(xmltio_FIND_REQUIRED)
SET(xmltio_REQUIRED "REQUIRED")
ENDIF()
PKG_CHECK_MODULES(xmltio ${xmltio_REQUIRED} ${MODULE})
FIND_LIBRARY(xmltio_LIBRARY
NAMES ${xmltio_LIBRARIES}
HINTS ${xmltio_LIBRARY_DIRS}
)
SET(xmltio_LIBRARIES ${xmltio_LIBRARY})
ENDIF()
IF(Memory_FOUND)
message(STATUS "found Memory")
include_directories(${Memory_INCLUDE_DIRS} ${xmltio_INCLUDE_DIRS})
add_executable(${PROJECT_NAME} main.cc)
target_link_libraries(${PROJECT_NAME} ${Memory_LIBRARIES} ${xmltio_LIBRARIES})
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin)
ENDIF()
# This is the part for Python SWIG:
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(main.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(main.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(main python main.i main.cc)
SWIG_LINK_LIBRARIES(main ${Memory_LIBRARIES} ${xmltio_LIBRARIES} ${PYTHON_LIBRARIES})
And this is how my main.i looks like:
/* File : main.i */
%module main
%{
/* Put headers and other declarations here */
extern int main(int argc, char *argv[]);
%}
extern int main(int argc, char *argv[]);
Any clue what went wrong here?
Is "main" maybe a bad name for this?
The swig invocation generates a source file that defines the init_main function. This file is either not compiled, or its object file is not linked into the shared object that constitutes your python extension.
Yes, main is a bad name, but here you are stuck at an earlier stage than where this might become a problem.
I easily tessellated two parametric 3D surfaces (both convex surfaces).
These are the two tessellated parametric surfaces:
Now, my intention is to join both in a single solid. But I'm obtaining this:
enter image description here
I'm using Qhull to create the Delaunay triangulation and it seems that works well for the 1st convex surface, but not for back surface. :(
This is my current code (parts taken from ZivS )
#include "Qhull.h"
using namespace orgQhull;
void myQhull::Qhull::runQhull3D(const pcl::PCLPointCloud2& pointCloud, const char* args)
{
std::cout << "runQhull vertices" << std::endl;
numVertices = 0;
std::stringstream verticesSS;
m_externalPoints = new PointCoordinates(3,""); //3 = dimension
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2(pointCloud, *cloud);
std::vector<double> allPoints;
for (unsigned int i = 0; i < cloud->size(); i++) {
allPoints.push_back(cloud->at(i).x);
allPoints.push_back(cloud->at(i).y);
allPoints.push_back(cloud->at(i).z);
verticesSS << cloud->at(i).x << " " << cloud->at(i).y << " " << cloud->at(i).z << "\n";
numVertices++;
}
vertices += verticesSS.str();
m_externalPoints->append(allPoints); //convert to vector<double>
runQhull(*m_externalPoints, args);
}
void myQhull::Qhull::runQhull(const PointCoordinates &points, const char *qhullCommand2)
{
std::string triangles;
std::stringstream ss;
numSimplices = 0;
int numFaces = 0;
std::cout << numVertices << std::endl;
std::cout << "runQhull facets" << std::endl;
orgQhull::Qhull qHull(points.comment().c_str(), points.dimension(), points.count(), &*points.coordinates(), qhullCommand2);
QhullFacetList facets = qHull.facetList();
for (QhullFacetList::iterator it = facets.begin(); it != facets.end(); ++it)
{
if (!(*it).isGood()) continue;
QhullFacet f = *it;
QhullVertexSet vSet = f.vertices();
auto coord = f.hyperplane().coordinates();
numFaces = vSet.size();
ss << numFaces;
for (QhullVertexSet::iterator vIt = vSet.begin(); vIt != vSet.end(); ++vIt)
{
QhullVertex v = *vIt;
QhullPoint p = v.point();
double * coords = p.coordinates();
ss << " " << p.id() << " ";
}
ss << "\n";
numSimplices++;
}
simplices += ss.str();
std::cout << numSimplices << std::endl;
}
void myQhull::Qhull::saveOff(std::string file)
{
std::cout << "Saving qhull.off" << std::endl;
std::ofstream offFile;
offFile.open(file);
offFile << "OFF\n";
offFile << numVertices << " " << numSimplices << " 0";
offFile << vertices;
offFile << simplices;
offFile.close();
}
void myQhull::Qhull::run(const pcl::PCLPointCloud2& pointCloud)
{
Qhull qhull;
qhull.runQhull3D(pointCloud, "Qt");
qhull.saveOff("qhull.off");
}
Also, I used greedy_projection from OpenCV but without any success. It is able only to perform the two surfaces tessellation without joining them.
Any idea why this is happening?
Finally I found the solution.
Adding "d" to qhull.runQhull3D(pointCloud, "d Qt") generates the correct Delaunay triangulation for upper and lower surface.
Therefore, as they are regular meshes I, manually, create the edge connecting vertices from the two surfaces.
Thank you.
In python we have library scipy containing sp.linalg.norm, sp.cross. Are there any similar functions in C++ boost library?
There doesn't seem to be.
However, OpenCV has what you need!
L2 norm: http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#norm
Cross: http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#Point_
#include <opencv2/opencv.hpp>
int main(int argc, const char *argv[])
{
cv::Point3d p1(1, 0, 0);
cv::Point3d p2(0, 1, 0);
cv::Point3d cross_prod = p1.cross(p2);
std::cout
<< "<" << cross_prod.x
<< ", " << cross_prod.y
<< ", " << cross_prod.z
<< ">"
<< std::endl;
std::cout << "L2 norm: " << cv::norm(cross_prod) << std::endl;
return 0;
}
The output:
<0, 0, 1>
L2 norm: 1
I am attempting to send a command that runs a specific python script: however, whenever the program reaches the execution line, this occurs:
Unhandled exception at 0x69bd1f16 in GameServer.exe: 0xC0000005: Access violation reading location 0x46f520ca.
The program stops resonding and crashes. Here is the method in question:
void ScriptManager::runScript(std::string scriptName, std::string args[])
{
std::string py = "python " + scriptName;
std::cout << py << std::endl;
for(int i = 0; i < args->length(); i++)
{
py += " " + args[i];
std::cout << py << std::endl;
}
std::cout << py << std::endl;
std::system(py.c_str());
}
This calls the above function:
void DBFactory::dbRegisterUser(std::string username, std::string password)
{
ScriptManager script;
std::string data[] = {username, password};
script.runScript("Python.py", data);
}
The script does not run, as far as I know. I can also post the script if it would help.
This is the problem:
for (int i = 0; i < args->length(); i++)
{
py += " " + args[i];
std::cout << py << std::endl;
}
args->length() is equivalent to args[0].length(); i.e. you're taking the length of the first string in the array and using that as an index. After two iterations pass, you're going to access past the end of the array. The best solutions are(all examples are UNTESTED):
Use an std::array(C++11 only):
void DBFactory::dbRegisterUser(std::string username, std::string password)
{
ScriptManager script;
script.runScript("Python.py", {username, password});
}
void ScriptManager::runScript(std::string scriptName, std::array<std::string, 2> args)
{
std::string py = "python " + scriptName;
std::cout << py << std::endl;
for (std::string s : args)
{
py += " " + s;
std::cout << py << std::endl;
}
std::cout << py << std::endl;
std::system(py.c_str());
}
Use an std::vector(the example uses C++03):
void DBFactory::dbRegisterUser(std::string username, std::string password)
{
ScriptManager script;
int tmp[2] = {username, password};
script.runScript("Python.py", std::vector<std::string>(&tmp[0], &tmp[0]+2));
}
void ScriptManager::runScript(std::string scriptName, std::vector<std::string> args)
{
std::string py = "python " + scriptName;
std::cout << py << std::endl;
for(std::vector<std::string>::iterator it = args.begin(); it != args.end(); it++)
{
py += " " + *it;
std::cout << py << std::endl;
}
std::cout << py << std::endl;
std::system(py.c_str());
}
Pass the array size as a parameter:
void DBFactory::dbRegisterUser(std::string username, std::string password)
{
ScriptManager script;
script.runScript("Python.py", {username, password}, 2);
}
void ScriptManager::runScript(std::string scriptName, std::string args[], int size)
{
std::string py = "python " + scriptName;
std::cout << py << std::endl;
for(int i=0; i<size; i++)
{
py += " " + args[i];
std::cout << py << std::endl;
}
std::cout << py << std::endl;
std::system(py.c_str());
}
I personally prefer example 1 and would avoid example 3 like the plague. Example 2 works well but probably isn't as fast as example 1.