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.
Related
I am in my third CS class online and I have done ok until now but I am really struggling with this. My code runs fine through the menu and input validation just fine but then as soon as I call a function from the python file I get the dereferencing null pointer message as follows " EXCEPTION UNHANDLED: Unhandled exception at 0x1DD09F27 (python36.dll) in moduleSixCppAndPython.exe: 0xC0000005: Access violation reading location 0x00000004. occurred".
I'm going to try to include my c++ code so forgive me if i mess this it up.. this is my first time using stackoverflow. the sections underlined in my IDE are the line as follows:
pFunc = PyDict_GetItemString(pDict, procname); // this one get like a red X next to it
...
Py_DECREF(pValue); // this line is underlined
all issues are coming from the "int callIntFunc(string proc, int param)" funtion
main is not really finished yet so i'm not super concerned with that unless that's where my problem is coming from...
any guidance at all would be very greatly appreciated!
#include <Python.h>
#include <iostream>
#include <Windows.h>
#include <cmath>
#include <string>
#include <conio.h>
using namespace std;
bool CONTINUE_RUN = true;
int displayMenu() {
int userInput = 0;
while (true) {
cout << "1: Display a Multiplication Table" << endl;
cout << "2: Double a Value" << endl;
cout << "3: Exit" << endl;
cout << "Enter your selection as a number 1, 2, or 3." << endl;
while (!(cin >> userInput)) {
system("cls");
cout << "ERROR: Please enter 1, 2, or 3" << endl;
cout << "1: Display a Multiplication Table" << endl;
cout << "2: Double a Value" << endl;
cout << "3: Exit" << endl;
cout << "Enter your selection as a number 1, 2, or 3." << endl;
cin.clear();
cin.ignore(123, '\n');
}
if (userInput == 1) {
break;
}
if (userInput == 2) {
break;
}
if (userInput == 3) {
CONTINUE_RUN = false;
break;
}
else {
system("cls");
cout << "ERROR: Please enter 1, 2, or 3" << endl;
continue;
}
}
return userInput;
}
int userData() {
int pickNum;
system("cls");
cout << "Please enter an integer: " << endl;
while (!(cin >> pickNum)) {
system("cls");
cout << "ERROR: Please enter an INTEGER:";
cin.clear();
cin.ignore(123, '\n');
}
return pickNum;
}
int callIntFunc(string proc, int param)
{
char* procname = new char[proc.length() + 1];
std::strcpy(procname, proc.c_str());
PyObject* pName, * pModule, * pDict, * pFunc, * pValue = nullptr, * presult = nullptr;
// Initialize the Python Interpreter
Py_Initialize();
// Build the name object
pName = PyUnicode_FromString((char*)"PythonCode");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, procname);
if (PyCallable_Check(pFunc))
{
pValue = Py_BuildValue("(i)", param);
PyErr_Print();
presult = PyObject_CallObject(pFunc, pValue);
PyErr_Print();
}
else
{
PyErr_Print();
}
//printf("Result is %d\n", _PyLong_AsInt(presult));
Py_DECREF(pValue);
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
// clean
delete[] procname;
return _PyLong_AsInt(presult);
}
int main(){
while (CONTINUE_RUN == true) {
int userNumber = 0;
int menuValue = displayMenu();
if (menuValue == 1) {
userNumber = userData();
system("cls");
int token = callIntFunc("MultiplicationTable", userNumber);
cout << "Press any key to continue" << endl;
_getch();
}
if (menuValue == 2) {
userNumber = userData();
system("cls");
cout << callIntFunc("DoubleValue", userNumber);
cout << "Press any key to continue" << endl;
_getch();
}
}
cout << "GOODBYE" << endl;
}
OK so a big THANK YOU to #PaulMcKenzie in the comments for pointing me in the right direction...
Turns out the issue was not in my .cpp file but in fact in the .py file that it was reading.
I had used the Python syntax :
print(namedVariable + "someString" + (evaluatedCalculation))
Now while this was technically correct for some instances it was creating unpredictable results when passed from my .py file back to my .cpp file. The error was flagging in my .cpp file so the real error that was made was that. I had tunnel vision in trying to find the error solely in the .cpp file and not anywhere else. PLEASE forgive a rookie of his rookie mistake here !
To fix this, I altered the syntax in my .py file to :
print(namedVariable, "someString", (evaluatedCalculation))
The true error here was not just in the logic I applied in writing my Python code... but in the logic I applied in finding the source of my error.
I learned much more in finding the flaw in my thinking than I did in finding the flaw in this code. But hey.. live and learn right?
Anyway,
happy coding !
Love and Respect !
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)
I'm embedding Python 3.8.2 in C++ code (using Visual Studio 2019). Python has pandasn installed (through pip).
I manage to import pandas from a C++ program, however, when I try to import it a second time, it crashs.
#include <Python.h>
#include <iostream>
int main( int argc, char* argv[] )
{
{
Py_SetPythonHome( L"C:\\Python38" );
// Initialize the Python Interpreter
Py_Initialize();
std::cout << "Importing pandas..." << std::endl;
if ( PyRun_SimpleString( "import pandas" ) == 0 )
std::cout << "SUCCESS" << std::endl;
else
std::cout << "FAIL" << std::endl;
Py_Finalize();
}
{
Py_SetPythonHome( L"C:\\Python38" );
// Initialize the Python Interpreter
Py_Initialize();
std::cout << "Importing pandas..." << std::endl;
if ( PyRun_SimpleString( "import pandas" ) == 0 )
std::cout << "SUCCESS" << std::endl;
else
std::cout << "FAIL" << std::endl;
Py_Finalize();
}
return 0;
}
This crashs with an exception:
_multiarray_umath.cp38-win_amd64.pyd!00007ffbd5b8ca69() Inconnu
_multiarray_umath.cp38-win_amd64.pyd!00007ffbd5b8ffd6() Inconnu
_multiarray_umath.cp38-win_amd64.pyd!00007ffbd5b9d34d() Inconnu
python38.dll!00007ffbd22f6131() Inconnu
python38.dll!00007ffbd22f6092() Inconnu
Output is:
Importing pandas...
SUCCESS
Importing pandas...
Traceback (most recent call last):
File "<string>", line 1, in <module>
Is there any init/uninit step I missed that could make this fail while it shaould work?
Note that I cannot Debug as pandas cannot be loaded in Debug build.
Upon request from OP, I made a small demo for how we wrap user Python scripts in our application to prevent that global variables of user scripts become unintended persistent:
#include <iostream>
#include <string>
#include <Python.h>
const char *PyScript = R"(try:
print(a)
except:
print("a not (yet) defined")
a = 123
print(a)
)";
std::string wrapPyScript(const char* script)
{
std::string source = std::string("def __mainPythonFunction():\n") + script;
{ const char *const indent = "\n ";
for (size_t i = source.size(); i--;) {
size_t n = 1;
switch (source[i]) {
case '\n': if (i && source[i - 1] == '\r') n = 2, --i;
case '\r': source.replace(i, n, indent); break;
}
}
}
source += "\n"
"pass\n"
"\n"
"try:\n"
" __mainPythonFunction()\n"
"except:\n"
" rf.form.appContext.notifyAbort()\n"
" raise\n";
return source;
}
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
DEBUG(Py_Initialize());
std::cout << "\nWithout wrapper:\n\n";
DEBUG(for (int i = 0; i < 2; ++i) {
DEBUG(PyRun_SimpleString(PyScript));
});
std::cout << "\nWith wrapper:\n\n";
DEBUG(for (int i = 0; i < 2; ++i) {
DEBUG(PyRun_SimpleString(wrapPyScript(PyScript).c_str()));
});
std::cout << '\n';
DEBUG(Py_Finalize());
}
Output:
Py_Initialize();
Without wrapper:
for (int i = 0; i < 2; ++i) { DEBUG(PyRun_SimpleString(PyScript)); };
PyRun_SimpleString(PyScript);
a not (yet) defined
123
PyRun_SimpleString(PyScript);
123
123
With wrapper:
for (int i = 0; i < 2; ++i) { DEBUG(PyRun_SimpleString(wrapPyScript(PyScript).c_str())); };
PyRun_SimpleString(wrapPyScript(PyScript).c_str());
a not (yet) defined
123
PyRun_SimpleString(wrapPyScript(PyScript).c_str());
a not (yet) defined
123
Py_Finalize();
However, I'm not quite sure whether this is enough to fix OPs issue with the imported Pandas library.
In our application (where we used the above trick), we import selected libraries once after the Py_Initialize().
(I remember roughly that this was our last desperate resort to fix similar issues like OP observed.)
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.