I'm trying to build multiple controllers. The original code that connect all switches to one controller is as follows:
void OFA_switch::connect()
{
socket.renewSocket();
int connectPort = par("connectPort");
/*
const char *connectAddress= par("connectAddress");
EV << "connectAddress = " << connectAddress << " connectPort =" << connectPort << endl;
if (getParentModule()->getParentModule()->getSubmodule("controller") != NULL)
{
// multiple controllers; full path is needed for connect address
connectAddress = (getParentModule()->getParentModule())->getSubmodule("controller")->getFullPath().c_str();
cModule *ctl = getSystemModule()->getSubmodule("controller");
if(ctl != NULL) {
EV << "ctl->getFullPath() = " << ctl->getFullPath().c_str() << endl;
connectAddress = ctl->getFullPath().c_str();
}
EV << "After: connectAddress = " << connectAddress << endl;
}
*/
L3Address ctlIPAddr;
EV << "connect L3Address = " << L3AddressResolver().tryResolve("controller", ctlIPAddr) << endl;
// EV << "result: connectAddress = " << ctlIPAddr << endl;
// socket.connect(L3AddressResolver().resolve(connectAddress), connectPort);
socket.connect(ctlIPAddr, connectPort);
}
I'm trying to make some switches connected to controller1 while the other switches connected to controller2, so I tried to adapt the following code to:
void My_OFA_switch::connect() {
socket.renewSocket();
int connectPort = par("connectPort");
const char *connectAddress = par("connectAddress");
EV << "connectAddress = " << connectAddress << " connectPort =" << connectPort << endl;
const char *connectAddr;
cModule *ctl;
if (strcmp (connectAddress, "controller1")==0)
{ connectAddr = (getParentModule())->getSubmodule("controller1")->getFullPath().c_str();
ctl = getSystemModule()->getSubmodule("controller1");
}
else if (strcmp (connectAddress, "controller2")==0)
{ connectAddr = (getParentModule())->getSubmodule("controller2")->getFullPath().c_str();
ctl = getSystemModule()->getSubmodule("controller2");
}
if(ctl != NULL) {
EV << "ctl->getFullPath() = " << ctl->getFullPath().c_str() << endl;
connectAddr = ctl->getFullPath().c_str();
}
L3Address ctlIPAddr;
EV << "connect L3Address = " << L3AddressResolver().tryResolve(connectAddr, ctlIPAddr) << endl;
socket.connect(ctlIPAddr, connectPort);
}
Also, there is a file Switch.cc which represents the controller behavior
"in ini file :
*.controller.behavior = "Switch" "that contain:
void Switch::initialize() {
cModule *ITModule =
getParentModule()->getSubmodule("ofa_controller");
controller = check_and_cast<OFA_controller *>(ITModule);
getParentModule()->subscribe("PacketIn",this); }
Should I change something here?
But when I run it the following runtime error appears and immediately close the simulation:
Simulation run has encountered a problem. Finished with error.
And in console it appeared:
Simulation terminated with exit code: -1073741819
Working directory: D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/myws/openflow/scenarios
Command line: ../openflow.exe -m -n ..;../../inet/src;../../inet/examples;../../inet/tutorials;../../inet/showcases --image-path=../images;../../inet/images -l ../../inet/src/INET My_2Domain_Ctrl.ini
Environment variables:
PATH=;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/myws/inet/src;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\mingw64\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/bin/server;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/bin;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/lib/amd64;.;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\mingw64\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\local\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\site_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\vendor_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\core_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2;
OMNETPP_ROOT=D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/
OMNETPP_IMAGE_PATH=D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\images
I really appreciate any guidance and help because I must do a lot of work and I'm running out of time.
enter image description here
One has to remember that strcmp() returns 0 if the contents of both strings are equal. And in C++ zero means false.
So if you want to do something when connectAddress is equal to "controller1", you should write:
if (strcmp (connectAddress, "controller1") == 0) {
// ...
}
Generally, in order to deal with a runtime exception in OMNeT++ do:
Set debug-on-errors=true in your omnetpp.ini.
Build the project in debug mode.
Start the simulation in debug (i.e. Run | Debug).
The simulation will stop in the line that causes an error and in the stack trace you may see the referenced calls.
Reference: Learn OMNeT++ with TicToc - Runtime errors
Related
( reported here
https://superuser.com/questions/1511981/windows-10-creating-and-deleting-directory-in-remote-location-netapp-in-a-loop this time with some more data and example program )
I am working on an issue - Create and deletion of directory on a loop in a small window gets incorrect response from API - it says directory deleted (returns true) but it stays there for some more time(say 20-30 milliseconds).
What can cause? The program runs fine on Windows 7 (NetApp storage or local disk). Windows 10 passes with local disk; but fails with NetApp storage. Need to sleep get the API (DeleteDirectory correct )
Wrote a code to reproduce in windows , c program (because admins wanted that way to rule out java, powershell etc )
#include "pch.h"
#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <direct.h>
using namespace std;
int main()
{
const char* sleepTimeAsString = std::getenv("SLEEP_TIME_MILLIS");
const char* remoteRoot = std::getenv("REMOTE_UNC_PATH");
if (sleepTimeAsString == NULL) {
std::cout << "env SLEEP_TIME_MILLIS needed: " << '\n';
}
if (remoteRoot == NULL) {
std::cout << "env REMOTE_UNC_PATH needed: " << '\n';
}
std::cout << "set REMOTE_UNC_PATH=" << remoteRoot << '\n';
std::cout << "set SLEEP_TIME_MILLIS=" << sleepTimeAsString << '\n';
CreateDirectory(remoteRoot,NULL);
std::cout << "version 0.10 " << '\n';
std::cout << "created " << remoteRoot << '\n';
string path = remoteRoot;
string mynode = "/childdirectory";
string path2 = path + mynode;
DWORD error= GetLastError();
std::cout << error << '\n';
long sleepTime = atol(sleepTimeAsString);
for (int i = 0; i < 1000; i++) {
std::cout << "loop "<< i << '\n';
if (!CreateDirectory( path2.c_str(), NULL)) {
DWORD errorlooped = GetLastError();
std::cout <<"failed to create " << errorlooped << '\n';
exit(-1);
}
else {
std::cout << "success created " << path2.c_str() << '\n';
}
Sleep(sleepTime);
if (!RemoveDirectory(path2.c_str())) {
DWORD errorlooped = GetLastError();
std::cout << "failed remove "<< errorlooped << '\n';
exit(-1);
}
else {
std::cout << "success deleted " << path2.c_str() << '\n';
}
Sleep(sleepTime);
}
}
Result table: Once I provide sufficient sleep between calls the test started passing on this NetApp directory.
OS Disk Sleep Time(ms) Result
Win7 Local 0 PASS
Win7 Remote 0 PASS
WIn10 Local 0 PASS
WIn10 Remote (NetApp) 0 FAIL
WIn10 Remote (NetApp) 10 FAIL
WIn10 Remote (NetApp) 20 FAIL
WIn10 Remote (NetApp) 40 PASS
What should I investigate more on this issue (before getting back to System administrators ) - Ideas welcome.
I currently try to set up communication between a Windows program and a µC.
I'll show you the code to initialize the port:
int serialCommunication::serialInit(void){
//non overlapped communication
hComm = CreateFile( gszPort.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if (hComm == INVALID_HANDLE_VALUE){
cout << "Error opening port." << endl;
return 0;
}
else{
cout << "Opened Port successfully." << endl;
}
if (SetCommMask(hComm, EV_RXCHAR) == FALSE){
cout << "Error setting communications mask." << endl;
return 0;
}
else{
SetCommMask(hComm, EV_RXCHAR);
cout << "Communications mask set successfully." << endl;
}
if (GetCommState(hComm, &dcbSerialParams) == FALSE){
cout << "Error getting CommState." << endl;
return 0;
}
else{
GetCommState(hComm, &dcbSerialParams);
cout << "CommState retrieved successfully" << endl;
}
dcbSerialParams.BaudRate = CBR_115200; // Setting BaudRate = 115200
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None
if (SetCommState(hComm, &dcbSerialParams) == FALSE){
cout << "Error setting CommState" << endl;
return 0;
}
else{
SetCommState(hComm, &dcbSerialParams);
cout << "CommState set successfully" << endl << endl;
cout << "+---CommState Parameters---+" << endl;
cout << "Baudrate = " << dcbSerialParams.BaudRate << endl;
cout << "ByteSize = " << static_cast<int>(dcbSerialParams.ByteSize) << endl; //static Cast, um int auszugeben und kein char
cout << "StopBits = " << static_cast<int>(dcbSerialParams.StopBits) << endl; //static Cast, um int auszugeben und kein char
cout << "Parity = " << static_cast<int>(dcbSerialParams.Parity) << endl; //static Cast, um int auszugeben und kein char
cout << "+--------------------------+" << endl;
}
/*------------------------------------ Setting Timeouts --------------------------------------------------*/
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE){
cout << "Error setting timeouts" << endl;
return 0;
}
else{
SetCommTimeouts(hComm, &timeouts);
cout << "Timeouts set successfully." << endl;
cout << "+--------------------------+" << endl;
return 1;
}
My Read function looks like this:
void serialCommunication::serialRead(void){
bool readStatus;
bool purgeStatus = 0;
bool correctData = 0;
cout << "Waiting for Data..." << endl; // Programm waits and blocks Port (like Polling)
readStatus = WaitCommEvent(hComm, &dwEventMask, 0);
if (readStatus == FALSE){
cout << "Error in setting WaitCommEvent." << endl;
}
else{
cout << "Data received." << endl;
do{
readStatus = ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, 0);
SerialBuffer += TempChar; // add tempchar to the string
}while (NoBytesRead > 0);
SerialBuffer.pop_back(); // Delete last sign in buffer, otherwise one "0" too much shows up, for example "23900" instead of "2390"
cout << endl << SerialBuffer << endl;
SerialBuffer = ""; // Reset string
}
So at some point, my µC sends the String "Init complete...!\r\n" after initializing some things. This works well.Init complete proof
Now after that, the communcation produces errors. I am getting Data I should not receive. The µC can only send data, if a specific string is sent to it by the PC. While debugging I could detect, that the µC never receives this specific string and therefore never sends data. In the following picture, I show you what gibberish I am receiving constantly though.
Receiving Gibberish
/EDIT: I am constantly receiving the same gibberish
The funny thing is, I even receive that data, when the µC is completely switched off (Serial Cables are still connected). So there has to be some data at the port, which just is not deleted. I tried to restart the PC aswell, but it didn't help either.
I will also show you my while loop on PC:
while (testAbbruch != 1){
pointer = acMessung(anzahlMessungen, average); // measurement with external multimeter
cout << endl;
cout << "Average: " << average << endl << endl;
if (average >= 30){
testAbbruch = 1; // there won't be a next while iteration
befehl = "stopCalibration\r\n";
serialTest.serialWrite(befehl);
serialTest.serialRead();
}
else{
cout << "Aktion: ";
std::getline (cin, befehl);
befehl = "increment"; //for debugging
if (befehl == "increment"){
befehl.append("\r\n"); // adding it, so the µC can detect the string correctly
serialTest.serialWrite(befehl);
serialTest.serialRead(); // µC has to answer
}
else if(befehl == "decrement"){
befehl.append("\r\n"); // adding it, so the µC can detect the string correctly
serialTest.serialWrite(befehl);
serialTest.serialRead(); // µC has to answer
}
befehl = ""; // string leeren für nächsten Aufruf
}
}
I know my program is far from perfect, but if I understood the serial Communication with Windows correctly, the buffer is deleted while reading.
Is there any clue you could give me?
EDIT// I just wrote a program that expects one of two inputs: One input is called "increment" the other one is called "decrement". Those inputs are sent to the µC via the serial communication port. Every time I try to send "increment" and instantly after that I am reading from the port, I receive the weird data from this picture. Now, every time I try to send "decrement" and instantly after that I am reading from the port, I receive the weird data from that picture.
//
So my guess is that the data somehow is changed and then looped back to the PC? But why and how?!
I have a code that I found on the internet that uses the function GetRawInputDeviceInfo, but it doesn't get the name of the device right. sometimes it doesn't get a name at all. I've searched for an answer and found out that people had this problem on windows XP and windows 7 to. I am using windows 10 so that doesn't really help me.
C++ - WinAPI get list of all connected USB devices (do i need to post the code itself? im new to stack overflow)
At the end of the day what I am trying to do is get the names of all the devices connected to my PC and print them out, but this function doesnt return the name of the mouse either, so if anyone has a suggestion on how to fix it or a better method to get the names Id'e love to hear you'r ideas. thanks in advance, -shon :)
EDIT2! the full code:
#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <set>
// Namespace
using namespace std;
// Main
int main()
{
// Program
cout << "USB Device Lister." << endl;
// Get Number Of Devices
UINT nDevices = 0;
GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
// Got Any?
if (nDevices < 1)
{
// Exit
cout << "ERR: 0 Devices?";
cin.get();
return 0;
}
// Allocate Memory For Device List
PRAWINPUTDEVICELIST pRawInputDeviceList;
pRawInputDeviceList = new RAWINPUTDEVICELIST[sizeof(RAWINPUTDEVICELIST) * nDevices];
// Got Memory?
if (pRawInputDeviceList == NULL)
{
// Error
cout << "ERR: Could not allocate memory for Device List.";
cin.get();
return 0;
}
// Fill Device List Buffer
int nResult;
nResult = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));
// Got Device List?
if (nResult < 0)
{
// Clean Up
delete[] pRawInputDeviceList;
// Error
cout << "ERR: Could not get device list.";
cin.get();
return 0;
}
std::set<std::string> DeviceList;
// Loop Through Device List
for (UINT i = 0; i < nDevices; i++)
{
// Get Character Count For Device Name
UINT nBufferSize = 0;
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
RIDI_DEVICENAME, // Get Device Name
NULL, // NO Buff, Want Count!
&nBufferSize); // Char Count Here!
// Got Device Name?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to get Device Name character count.. Moving to next device." << endl << endl;
// Next
continue;
}
// Allocate Memory For Device Name
WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];
// Got Memory
if (wcDeviceName == NULL)
{
// Error
cout << "ERR: Unable to allocate memory for Device Name.. Moving to next device." << endl << endl;
// Next
continue;
}
// Get Name
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
RIDI_DEVICENAME, // Get Device Name
wcDeviceName, // Get Name!
&nBufferSize); // Char Count
// Got Device Name?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to get Device Name.. Moving to next device." << endl << endl;
// Clean Up
delete[] wcDeviceName;
// Next
continue;
}
// Set Device Info & Buffer Size
RID_DEVICE_INFO rdiDeviceInfo;
rdiDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
nBufferSize = rdiDeviceInfo.cbSize;
// Get Device Info
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice,
RIDI_DEVICEINFO,
&rdiDeviceInfo,
&nBufferSize);
// Got All Buffer?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to read Device Info.. Moving to next device." << endl << endl;
// Next
continue;
}
// Mouse
if (rdiDeviceInfo.dwType == RIM_TYPEMOUSE)
{
// Current Device
int id = rdiDeviceInfo.mouse.dwId; //device id
string s = "ID: " + std::to_string(id) + ", Type : MOUSE"; //device type is mouse
DeviceList.insert(s);
}
// Keyboard
else if (rdiDeviceInfo.dwType == RIM_TYPEKEYBOARD)
{
// Current Device
cout << endl << "Displaying device " << i + 1 << " information. (KEYBOARD)" << endl;
wcout << L"Name " << wcDeviceName << endl; //*Problem is here!* //
cout << "Keyboard mode: " << rdiDeviceInfo.keyboard.dwKeyboardMode << endl;
cout << "Number of function keys: " << rdiDeviceInfo.keyboard.dwNumberOfFunctionKeys << endl;
cout << "Number of indicators: " << rdiDeviceInfo.keyboard.dwNumberOfIndicators << endl;
cout << "Number of keys total: " << rdiDeviceInfo.keyboard.dwNumberOfKeysTotal << endl;
cout << "Type of the keyboard: " << rdiDeviceInfo.keyboard.dwType << endl;
cout << "Subtype of the keyboard: " << rdiDeviceInfo.keyboard.dwSubType << endl;
}
// Some HID
else // (rdi.dwType == RIM_TYPEHID)
{
// Current Device
cout << endl << "Displaying device " << i + 1 << " information. (HID)" << endl;
wcout << L"Device Name: " << wcDeviceName << endl;
cout << "Vendor Id:" << rdiDeviceInfo.hid.dwVendorId << endl;
cout << "Product Id:" << rdiDeviceInfo.hid.dwProductId << endl;
cout << "Version No:" << rdiDeviceInfo.hid.dwVersionNumber << endl;
cout << "Usage for the device: " << rdiDeviceInfo.hid.usUsage << endl;
cout << "Usage Page for the device: " << rdiDeviceInfo.hid.usUsagePage << endl;
}
// Delete Name Memory!
delete[] wcDeviceName;
}
// Clean Up - Free Memory
delete[] pRawInputDeviceList;
for (std::set<string>::iterator i = DeviceList.begin(); i != DeviceList.end(); ++i)
std::cout << *i << '\n';
// Exit
cout << endl << "Finnished.";
cin.get();
return 0;
}
In Windows there are two flavors of API calls: Unicode and ANSI. The former takes and returns UTF-16 encoded Unicode strings; the latter takes and returns 8-bit encoded strings (the exact encoding depends on the OS localization).
You choose which flavor you want to use by #defining (or not #defining) the macro UNICODE. Depending on that the function changes name, with an W or A suffix.
#ifdef UNICODE
#define GetRawInputDeviceInfo GetRawInputDeviceInfoW
#else
#define GetRawInputDeviceInfo GetRawInputDeviceInfoA
#endif
All the structures that may contain text data are also duplicated with the W or A suffixes.
Now your problem: you are not defining UNICODE so you are actually calling GetRawInputDeviceInfoA(), the ANSI flavor, that expects a char*, but you are passing a WCHAR*, that is a UNICODE string!
The solution is easy:
char* wcDeviceName = new char[nBufferSize + 1];
It is unfortunate that this function GetRawInputDeviceInfo() has its arguments overloaded, so it is declared as taking a void*, so the compiler cannot catch the error. If you were calling a simpler function, say SetWindowText() then you would have got a compiler error because of incompatible pointer type.
If you really want the full UNICODE name of the device, you may prefer keep the WCHAR string and then call the UNICODE function specifically:
WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];
...
GetRawInputDeviceInfoW(..., RIDI_DEVICENAME, wcDeviceName, ...);
When some application in OS X has multiple windows (many open documents, each in own window), it seems that all them share the same system menu, at least in FLTK. Is there a way to find the most recent selected window to send an event to it from the menu?
Here is my setup (Mac OS X 10.6.2, FLTK 1.3.3): have Shell class with system menu. Each time new document is opened, new Shell is created:
#ifdef __APPLE__
void Shell::macOpen(const char *fileName)
{
// If there are empty shell, open the model in it
if (s_empty != 0)
{
...
s_empty = 0;
}
// Otherwise, create new shell with the model
else
{
char *args[1];
args[0] = (char *) fileName;
new Shell(1, args, s_conf, s_dct, fileName, 1);
}
}
#endif
Then I keep track on the most recently selected Shell saving it into static Shell *Shell::s_current:
int Shell::handle(int event)
{
...
case FL_FOCUS:
#ifdef __APPLE__
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
#endif
return 1;
...
}
This piece seems to work, as I can see the traces each time I select some Shell:
Select shell with address: [0x8206db0]
Select shell with address: [0x82375f0]
Select shell with address: [0x5d20650]
Select shell with address: [0x82375f0]
Now, given:
Shell *Shell::currentShell(Fl_Widget *w)
{
cout << "Widget address: [" << w << "]" << endl;
Shell *result = 0;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#ifdef __APPLE__
else
{
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
}
#endif
return result;
}
I have some callback:
void Shell::shortcutCB(Fl_Widget *w, void *data)
{
cout << "Shortcut" << endl;
Shell *ref = currentShell(w);
if (ref != 0)
{
...
}
}
When this callback is executed from the menu and more Shells are open, I get the following error:
Bus error
With no trace from either Shell::shortcutCB or Shell::currentShell. When the only Shell is open, all works perfectly. When more Shells are open and I close all but one, the error arises again. There is no problems when the same callback is called from some widget within Shell or is delivered from keyboard shortcut.
Solved the problem with the following 3 steps:
Declaring manu bar in OS X also static (here was the fail):
#ifdef __APPLE__
static Fl_Sys_Menu_Bar *s_menubar;
#else
Fl_Sys_Menu_Bar *m_menubar;
#endif
Save current Shell::s_current not only on FL_FOCUS event, but on any event handled by Shell, that is, each time it returns 1:
int Shell::handle(int event)
{
int result = 0;
switch (event)
{
// Set result = 1 when handling the event
...
}
#ifdef __APPLE__
if (result == 1)
{
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
}
#endif
return result;
}
Use Shell::s_current for menu callbacks on OS X regardless of generating widget of the call:
Shell *Shell::currentShell(Fl_Widget *w)
{
Shell *result = 0;
#ifdef __APPLE__
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
#else
cout << "Widget address: [" << w << "]" << endl;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#endif
return result;
}
I am getting started with opencl in VS using this tutorial:
https://opencl.codeplex.com/wikipage?title=OpenCL%20Tutorials%20-%201
I am having trouble with setting up the host program. This is the code so far:
const char* clewErrorString(cl_int error) {
//stuff
}
int main(int argc, char **argv) {
cl_int errcode_ret;
cl_uint num_entries;
// Platform
cl_platform_id platforms;
cl_uint num_platforms;
num_entries = 1;
cout << "Getting platform id..." << endl;
errcode_ret = clGetPlatformIDs(num_entries, &platforms, &num_platforms);
if (errcode_ret != CL_SUCCESS) {
cout << "Error getting platform id: " << clewErrorString(errcode_ret) << endl;
exit(errcode_ret);
}
cout << "Success!" << endl;
// Device
cl_device_type device_type = CL_DEVICE_TYPE_GPU;
num_entries = 1;
cl_device_id devices;
cl_uint num_devices;
cout << "Getting device id..." << endl;
errcode_ret = clGetDeviceIDs(platforms, device_type, num_entries, &devices, &num_devices);
if (errcode_ret != CL_SUCCESS) {
cout << "Error getting device id: " << clewErrorString(errcode_ret) << endl;
exit(errcode_ret);
}
cout << "Success!" << endl;
// Context
cl_context context;
cout << "Creating context..." << endl;
context = clCreateContext(0, num_devices, &devices, NULL, NULL, &errcode_ret);
if (errcode_ret < 0) {
cout << "Error creating context: " << clewErrorString(errcode_ret) << endl;
exit(errcode_ret);
}
cout << "Success!" << endl;
// Command-queue
cl_command_queue queue;
cout << "Creating command queue..." << endl;
queue = clCreateCommandQueue(context, devices, 0, &errcode_ret);
if (errcode_ret != CL_SUCCESS) {
cout << "Error creating command queue: " << clewErrorString(errcode_ret) << endl;
exit(errcode_ret);
}
cout << "Success!" << endl;
return 0;
}
This doesn't compile, though: I get an error C4996: 'clCreateCommandQueue': was declared deprecated when i try to compile. I don't understand the whole setup process as of yet, so I don't know if I have messed up something or not. According to chronos, the function doesn't seem to be deprecated though:
https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateCommandQueue.html
If I remove the command queue part, the rest runs without problems. How can I make this work?
The clCreateCommandQueue function was deprecated as of OpenCL 2.0, and replaced with clCreateCommandQueueWithProperties. If you are only targeting devices that support OpenCL 2.0 (some recent Intel and AMD processors at the time of writing), you can safely use this new function.
If you need your code to run on devices that don't yet support OpenCL 2.0, you can continue using the deprecated clCreateCommandQueue function by using the preprocessor macros that the OpenCL headers provide, e.g:
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#include <CL/cl.h>