C++ LNK Error 2019 - c++

rmap_utils.h
#ifndef UTILS_RANGE_MAP_H
#define UTILS_RANGE_MAP_H
#include <stdlib.h>
#include <string>
#include <stdio.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
#include "opencv2\opencv.hpp"
class rmap_utils
{
public:
rmap_utils::rmap_utils(){}
rmap_utils::~rmap_utils(){}
int loadRmap(const std::string &path, float *& xMap, float *& yMap, float *& zMap, unsigned char *&rgbMap, int &height, int &width);
cv::Mat visualize_depth_image(float *img, int width, int height, bool visualize, std::string wName = "rangeMap");
cv::Mat visualize_rgb_image(unsigned char *img, int width, int height, bool visualize, std::string wName = "rangeMap");
cv::Mat visualize_normalized_rgb_image(float *img, int width, int height, bool visualize, std::string wName = "rangeMap");
float compute_rangeMap_resolution(float *xMap, float *yMap, float *zMap, int width, int height);
};
#endif
rmap_utils.cpp
#include "rmap_utils.h"
void Tokenize(const std::string &line, std::vector<std::string> &tokens, const std::string &delimiters = " ", const bool skipEmptyCells = true, const int maxNumTokens = std::numeric_limits<int>::max())
{
tokens.clear();
int nTokens = 0;
std::string::size_type pos = 0;
std::string::size_type lastPos = 0;
if(skipEmptyCells)
{
// Skip delimiters at beginning.
lastPos = line.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
pos = line.find_first_of(delimiters, lastPos);
while ( (std::string::npos != pos || std::string::npos != lastPos) && (nTokens < maxNumTokens) )
{
// Found a token, add it to the vector.
tokens.push_back(line.substr(lastPos, pos - lastPos));
nTokens++;
// Skip delimiters
lastPos = line.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = line.find_first_of(delimiters, lastPos);
}
}
else
{
while ( (std::string::npos != pos) && (nTokens < maxNumTokens) )
{
pos = line.find_first_of(delimiters, lastPos);
tokens.push_back(line.substr(lastPos, pos - lastPos));
nTokens++;
lastPos = pos+1;
}
}
}
template <typename T> void Read_Array(std::ifstream &filev, T* &aData, unsigned long int &nData, const bool binaryFile = true)
{
if (!filev.is_open() )
{
std::cout << "ERROR (Read_Array): file is not open";
getchar();
exit(-1);
}
if(binaryFile)
{
//read number of elements
filev.read((char*)&nData, sizeof(nData) );
aData = new T[nData];
//read data
filev.read((char*)aData, sizeof(T)*nData );
if(filev.gcount() != (sizeof(T)*nData) )
{
std::cout << "ERROR (Read_Array): filev.gcount() != (sizeof(T)*nData) " << filev.gcount() << " " << (sizeof(T)*nData) << std::endl;
std::cout << "Are you sure you opened the file in binary mode?";
getchar();
exit(-1);
}
if(!filev.good())
{
std::cout << "ERROR (Read_Array): !filev.good() [eof fail bad] [" << filev.eof() << " " << filev.fail() << " " << filev.bad() << "]" << std::endl;
std::cout << "Are you sure you opened the file in binary mode?";
getchar();
exit(-1);
}
}
else
{
//read number of elements
std::string line;
std::getline(filev, line);
filev >> nData;
aData = new T[nData];
//read data
T* ptrData = aData;
for(unsigned long int da=0; da<nData; da++)
{
filev >> *ptrData;
ptrData++;
}
std::getline(filev, line);
if(!filev.good())
{
std::cout << "ERROR (Read_Array): !filev.good() [eof fail bad] [" << filev.eof() << " " << filev.fail() << " " << filev.bad() << "]" << std::endl;
getchar();
exit(-1);
}
}
}
template <typename T> void Read_Vector(std::ifstream &filev, std::vector<T> &vData, const bool binaryFile = true)
{
if (!filev.is_open() )
{
std::cout << "ERROR (Read_Vector): file is not open";
getchar();
exit(-1);
}
unsigned long int nData = 0;
if(binaryFile)
{
//read number of elements
filev.read((char*)&nData, sizeof(nData) );
vData.resize((size_t)nData);
//read data
filev.read((char*)(&vData[0]), sizeof(T)*nData );
if(filev.gcount() != (sizeof(T)*nData) )
{
std::cout << "ERROR (Read_Vector): filev.gcount() != (sizeof(T)*nData) " << filev.gcount() << " " << (sizeof(T)*nData) << std::endl;
std::cout << "Are you sure you opened the file in binary mode?";
getchar();
exit(-1);
}
if(!filev.good())
{
std::cout << "ERROR (Read_Vector): !filev.good() [eof fail bad] [" << filev.eof() << " " << filev.fail() << " " << filev.bad() << "]" << std::endl;
std::cout << "Are you sure you opened the file in binary mode?";
getchar();
exit(-1);
}
}
else
{
//read number of elements
std::string line;
std::getline(filev, line);
filev >> nData;
vData.resize((size_t)nData);
//read data
T* ptrData = &vData[0];
for(unsigned long int da=0; da<nData; da++)
{
filev >> (*ptrData);
ptrData++;
}
std::getline(filev, line);
if(!filev.good())
{
std::cout << "ERROR (Read_Vector): !filev.good() [eof fail bad] [" << filev.eof() << " " << filev.fail() << " " << filev.bad() << "]" << std::endl;
getchar();
exit(-1);
}
}
}
template<typename T> T LexicalCast(const std::string& s)
{
std::stringstream ss(s);
T result;
if ((ss >> result).fail() || !(ss >> std::ws).eof())
{
//throw std::bad_cast();
std::cout << "ERROR:Impossible to cast " << s;
getchar();
exit(-1);
}
return result;
}
//passi i puntatori vuoti e lui elaborando li riempe per come ti servono
int loadRmap(const std::string &path, float *& xMap, float *& yMap, float *& zMap, unsigned char *&rgbMap, int &height, int &width)
{
bool binaryFile = true;
std::ifstream in(path.c_str(), std::ios::binary|std::ios::in);
if(!in.is_open())
{
std::cout << "ERROR (RangeMap::Load_RMap): Problems opening file";
getchar();
exit(-1);
}
std::string line;
std::vector<std::string> tokens;
int nValidPoints = 0;
bool texture = false;
int nChannels = 1;
double resolution;
//read header
while (!in.eof())
{
getline (in, line);
// Ignore empty lines
if (line == "")
continue;
// Tokenize the line
Tokenize(line, tokens, "\t\r " );
// first line
if (tokens[0] == "RMap")
continue;
// version
if (tokens[0] == "version")
{
continue;
}
// height
if (tokens[0] == "height")
{
height = LexicalCast<int>(tokens[1]);
continue;
}
// width
if (tokens[0] == "width")
{
width = LexicalCast<int>(tokens[1]);
continue;
}
// nValidPoints
if (tokens[0] == "nValidPoints")
{
nValidPoints = LexicalCast<int>(tokens[1]);
continue;
}
// resolution
if (tokens[0] == "resolution")
{
resolution = LexicalCast<double>(tokens[1]);
continue;
}
// texture
if (tokens[0] == "texture")
{
texture = true;
if (tokens[1] == "GrayScale")
{
nChannels = 1;
}
else if (tokens[1] == "BGR")
{
nChannels = 3;
}
else
{
std::cout << "ERROR (RangeMap::Load_RMap): tokens[1] != \"GrayScale\" and tokens[1] != \"BGR\" ";
getchar();
exit(-1);
}
continue;
}
// end_header
if (tokens[0] == "headerEnd")
{
break;
}
}
if(in.eof())
{
in.close();
std::cout << "ERROR (RangeMap::Load_RMap): end_header tag not reached";
getchar();
exit(-1);
}
//read valid point map
bool* validMap = NULL;
unsigned long int nTotalPoints = 0;
Read_Array(in, validMap, nTotalPoints, binaryFile);
if(nTotalPoints != width*height)
{
in.close();
std::cout << "ERROR (RangeMap::Load_RMap): nTotalPoints != m_width*m_height " << nTotalPoints << " != " << width << " * " << height << std::endl;
getchar();
exit(-1);
}
//read maps
std::vector<float> xVals;
std::vector<float> yVals;
std::vector<float> zVals;
Read_Vector(in, xVals, binaryFile);
Read_Vector(in, yVals, binaryFile);
Read_Vector(in, zVals, binaryFile);
if(xVals.size() != nValidPoints)
{
in.close();
std::cout << "ERROR (RangeMap::Load_RMap): vMap_X.size() != nValidPoints " << xVals.size() << " != " << nValidPoints << std::endl;
getchar();
exit(-1);
}
if(yVals.size() != nValidPoints)
{
in.close();
std::cout << "ERROR (RangeMap::Load_RMap): vMap_Y.size() != nValidPoints " << yVals.size() << " != " << nValidPoints << std::endl;
getchar();
exit(-1);
}
if(zVals.size() != nValidPoints)
{
in.close();
std::cout << "ERROR (RangeMap::Load_RMap): vMap_Z.size() != nValidPoints " << zVals.size() << " != " << nValidPoints << std::endl;
getchar();
exit(-1);
}
//if(xMap)
//{
// delete[] xMap;
//}
xMap = new float[width*height];
/*if(yVals)
{
delete[] yVals;
}*/
yMap = new float[width*height];
/*if(zVals)
{
delete[] zVals;
}*/
zMap = new float[width*height];
float* ptrvMap_X = &xVals[0];
float* ptrvMap_Y = &yVals[0];
float* ptrvMap_Z = &zVals[0];
bool* ptrValidMap = validMap;
float* ptrXmap = xMap;
float* ptrYmap = yMap;
float* ptrZmap = zMap;
for(unsigned long int po=0; po<nTotalPoints; po++)
{
if(*ptrValidMap)
{
*ptrXmap = *(ptrvMap_X++);
*ptrYmap = *(ptrvMap_Y++);
*ptrZmap = *(ptrvMap_Z++);
}
else
{
*ptrZmap = std::numeric_limits<float>::quiet_NaN();
}
ptrXmap++;
ptrYmap++;
ptrZmap++;
ptrValidMap++;
}
delete[] validMap;
//read texture
if(texture)
{
IplImage* m_texture = cvCreateImage(cvSize(width, height), 8, nChannels);
rgbMap = new unsigned char[width*height*3];
in.read( (char*)(m_texture->imageData), height*m_texture->widthStep );
if(in.gcount() != height*m_texture->widthStep)
{
std::cout << "ERROR (RangeMap::Load_RMap): in.gcount() != m_height*m_texture->widthStep " << in.gcount() << " " << height*m_texture->widthStep;
getchar();
exit(-1);
}
if(!in.good())
{
std::cout << "ERROR (RangeMap::Load_RMap): !in.good() in reading m_texture [eof fail bad] [" << in.eof() << " " << in.fail() << " " << in.bad() << "]";
getchar();
exit(-1);
}
for (int j=0; j<height; j++)
{
for ( int i=0; i<width; i++)
{
if ( nChannels == 3)
{
rgbMap[ j*width*3+i*3 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i*3];
rgbMap[ j*width*3+i*3 +1 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i*3 +1];
rgbMap[ j*width*3+i*3 +2 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i*3 +2];
}
else
{
rgbMap[ j*width*3+i*3+2 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i];
rgbMap[ j*width*3+i*3+1 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i];
rgbMap[ j*width*3+i*3 ] = ((unsigned char *)(m_texture->imageData))[ j * m_texture->widthStep + i];
}
}
}
/*cvNamedWindow("cicciux", 0);
cvShowImage("cicciux", m_texture);
cvWaitKey(0);*/
cvReleaseImage(&m_texture);
}
else
{
rgbMap = NULL;
}
in.close();
return nValidPoints;
}
cv::Mat visualize_depth_image(float *img, int width, int height, bool visualize, std::string wName)
{
cv::Mat mat(height, width, CV_8UC3);
float dmax = -1;
float dmin = std::numeric_limits<float>::max();
for ( int j=0; j<height; j++)
{
for ( int i=0; i<width; i++)
{
if ( img[j*width+i] == img[j*width+i] )
{
if ( img[j*width+i] > dmax )
dmax = img[j*width+i];
if (img[j*width+i]<dmin)
dmin = img[j*width+i];
}
}
}
for ( int j=0; j<height; j++)
{
for ( int i=0; i<width; i++)
{
if ( img[j*width+i] == img[j*width+i] )
{
unsigned char pixel = cv::saturate_cast<unsigned char>( ((img[j*width+i] - dmin)* 255.0f) / (dmax-dmin) ) ;
mat.at<cv::Vec3b>(j,i)[0] = pixel;
mat.at<cv::Vec3b>(j,i)[1] = pixel;
mat.at<cv::Vec3b>(j,i)[2] = pixel;
}
else
{
mat.at<cv::Vec3b>(j,i)[0] = 0;
mat.at<cv::Vec3b>(j,i)[1] = 0;
mat.at<cv::Vec3b>(j,i)[2] = 255;
}
}
}
if ( visualize)
{
cv::imshow(wName, mat);
cv::waitKey(0);
}
return mat;
}
cv::Mat visualize_rgb_image(unsigned char *img, int width, int height, bool visualize, std::string wName)
{
cv::Mat mat(height, width, CV_8UC3);
for ( int j=0; j<height; j++)
{
for ( int i=0; i<width; i++)
{
for ( int c=0; c<3; c++)
{
mat.at<cv::Vec3b>(j,i)[c] = img[j*width*3 + i*3 + c];
}
}
}
if ( visualize )
{
cv::imshow(wName, mat);
cv::waitKey(0);
}
return mat;
}
cv::Mat visualize_normalized_rgb_image(float *img, int width, int height, bool visualize, std::string wName)
{
cv::Mat mat(height, width, CV_8UC3);
for ( int j=0; j<height; j++)
{
for ( int i=0; i<width; i++)
{
for ( int c=0; c<3; c++)
{
mat.at<cv::Vec3b>(j,i)[c] = static_cast<unsigned char>(std::floor(img[j*width*3 + i*3 + c] * 255));
}
}
}
if ( visualize)
{
cv::imshow(wName, mat);
cv::waitKey(0);
}
return mat;
}
float compute_rangeMap_resolution(float *xMap, float *yMap, float *zMap, int width, int height)
{
float res = 0.0f;
int nCount = 0;
for ( int j=0; j<height-1; j++)
{
for ( int i=0; i<width-1; i++)
{
if ( zMap[j*width+i] == zMap[j*width+i] )
{
if ( zMap[j*width+i+1] == zMap[j*width+i+1] )
{
nCount ++ ;
res += (zMap[j*width+i]-zMap[j*width+i+1])*(zMap[j*width+i]-zMap[j*width+i+1]) + (yMap[j*width+i]-yMap[j*width+i+1])*(yMap[j*width+i]-yMap[j*width+i+1]) + (xMap[j*width+i]-xMap[j*width+i+1])*(xMap[j*width+i]-xMap[j*width+i+1]);
}
if ( zMap[(j+1)*width+i] == zMap[(j+1)*width+i] )
{
nCount ++ ;
res += (zMap[j*width+i]-zMap[(j+1)*width+i])*(zMap[j*width+i]-zMap[(j+1)*width+i]) + (yMap[j*width+i]-yMap[(j+1)*width+i])*(yMap[j*width+i]-yMap[(j+1)*width+i]) + (xMap[j*width+i]-xMap[(j+1)*width+i])*(xMap[j*width+i]-xMap[(j+1)*width+i]);
}
}
}
}
res /= nCount;
res = sqrt(res);
return res;
}
Error List:
error LNK2019: unresolved external symbol "public: int __cdecl rmap_utils::loadRmap(class std::basic_string,class std::allocator > const &,float * &,float * &,float * &,unsigned char * &,int &,int &)" (?loadRmap#rmap_utils##QEAAHAEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##AEAPEAM11AEAPEAEAEAH3#Z) referenced in function main

In rmap_utils.cpp replace
int loadRmap(const std::string &path, float *& xMap, float *& yMap, float *& zMap, unsigned char *&rgbMap, int &height, int &width)
With:
int rmap_utils::loadRmap(const std::string &path, float *& xMap, float *& yMap, float *& zMap, unsigned char *&rgbMap, int &height, int &width)

Related

Enumerate removable drives on Linux and macOS

On Windows I am able to enumerate removable drives using FindFirstVolume, FindNextVolume, GetVolumePathNamesForVolumeName and the GetDriveType functions. How can I achieve this on Linux and macOS?
On macOS you need to work with IOKit: https://developer.apple.com/documentation/iokit
It can looks like the following code:
#include <cstdlib>
#include <iostream>
#include <mach/mach_port.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOTypes.h>
#include <IOKit/IOKitKeys.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
std::string get_descriptor_idx(IOUSBDeviceInterface **dev, UInt8 idx);
int main(int argc, char *argv[]) {
/*
* Get the IO registry
*/
auto entry = IORegistryGetRootEntry(kIOMasterPortDefault);
if (entry == 0)
return EXIT_FAILURE;
io_iterator_t iter{};
auto kret = IORegistryEntryCreateIterator(entry, kIOUSBPlane, kIORegistryIterateRecursively, &iter);
if (kret != KERN_SUCCESS || iter == 0)
return EXIT_FAILURE;
io_service_t service {};
std::cout << std::endl;
while ((service = IOIteratorNext(iter))) {
IOCFPlugInInterface **plug = nullptr;
IOUSBDeviceInterface **dev = nullptr;
io_string_t path;
SInt32 score = 0;
IOReturn ioret;
kret = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plug, &score);
IOObjectRelease(service);
if (kret != KERN_SUCCESS || plug == nullptr) {
continue;
}
/*
* USB
*/
ioret = (*plug)->QueryInterface(plug, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
static_cast<LPVOID *>((void *) &dev));
(*plug)->Release(plug);
if (ioret != kIOReturnSuccess || dev == nullptr) {
continue;
}
if (IORegistryEntryGetPath(service, kIOServicePlane, path) != KERN_SUCCESS) {
(*dev)->Release(dev);
continue;
}
std::cout << "USB Path: " << path << std::endl;
UInt8 si;
UInt16 u16v;
if ((*dev)->GetDeviceVendor(dev, &u16v) == kIOReturnSuccess)
std::cout << "VID: "<< u16v << std::endl;
if ((*dev)->GetDeviceProduct(dev, &u16v) == kIOReturnSuccess)
std::cout << "PID: "<< u16v << std::endl;
if ((*dev)->USBGetManufacturerStringIndex(dev, &si) == kIOReturnSuccess) {
std::cout << "Manufacturer: " << get_descriptor_idx(dev, si) << std::endl;
}
if ((*dev)->USBGetProductStringIndex(dev, &si) == kIOReturnSuccess) {
std::cout << "Product: " << get_descriptor_idx(dev, si) << std::endl;
}
(*dev)->Release(dev);
std::cout << std::endl;
}
IOObjectRelease(iter);
return 0;
}
/* a quick version */
std::string get_descriptor_idx(IOUSBDeviceInterface **dev, UInt8 idx)
{
IOUSBDevRequest request;
IOReturn ioret;
char buffer[4086] = { 0 };
CFStringRef cfstr;
CFIndex len;
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
request.wValue = (kUSBStringDesc << 8) | idx;
request.wIndex = 0x409;
request.wLength = sizeof(buffer);
request.pData = buffer;
ioret = (*dev)->DeviceRequest(dev, &request);
if (ioret != kIOReturnSuccess)
return "n/a";
if (request.wLenDone <= 2)
return "n/a";
cfstr = CFStringCreateWithBytes(nullptr, (const UInt8 *)buffer+2, request.wLenDone-2, kCFStringEncodingUTF16LE, 0);
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8) + 1;
if (len < 0) {
CFRelease(cfstr);
return "n/a";
}
std::string str; str.resize(len);
CFStringGetCString(cfstr, str.data(), len, kCFStringEncodingUTF8);
CFRelease(cfstr);
return str;
}
In my case the result ıs:
USB Path: IOService:/AppleARMPE/arm-io/xxxx/USB2.1 Hub#01100000
VID: 1507
PID: 1552
Manufacturer: GenesysLogic
Product: USB2.1 USB

Mxnet c++ inference with MXPredSetInput segmentation fault

Mxnet c++ inference with MXPredSetInput segmentation fault
1. background
I have tried https://github.com/apache/incubator-mxnet/tree/master/example/image-classification/predict-cpp successed.
But when I try to deploy mxnet in c++ with my own model, I met a segmentation fault error:
[17:33:07] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v1.2.1. Attempting to upgrade...
Signal: SIGSEGV (Segmentation fault)
2. code with error:
MXPredSetInput(pred_hnd, "data", image_data.data(), static_cast<mx_uint>(image_size));
3. tips
First I thought it's because of input data shape not compatible with the model input layer.But I ask model designer, it's a resnet model with conv only, so, any kind input shape should be OK.
4. Download model:
Download them, and put them into model dir.
https://drive.google.com/drive/folders/16MEKNOz_iwquVxHMk9c7igmBNuT6w7wz?usp=sharing
4. code: find: https://github.com/jaysimon/mxnet_cpp_infere
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <thread>
#include <iomanip>
#include <opencv2/opencv.hpp>
// Path for c_predict_api
#include <mxnet/c_predict_api.h>
const mx_float DEFAULT_MEAN = 117.0;
static std::string trim(const std::string& input) {
auto not_space = [](int ch) {
return !std::isspace(ch);
};
auto output = input;
output.erase(output.begin(), std::find_if(output.begin(), output.end(), not_space));
output.erase(std::find_if(output.rbegin(), output.rend(), not_space).base(), output.end());
return output;
}
// Read file to buffer
class BufferFile {
public :
std::string file_path_;
std::size_t length_ = 0;
std::unique_ptr<char[]> buffer_;
explicit BufferFile(const std::string& file_path)
: file_path_(file_path) {
std::ifstream ifs(file_path.c_str(), std::ios::in | std::ios::binary);
if (!ifs) {
std::cerr << "Can't open the file. Please check " << file_path << ". \n";
return;
}
ifs.seekg(0, std::ios::end);
length_ = static_cast<std::size_t>(ifs.tellg());
ifs.seekg(0, std::ios::beg);
std::cout << file_path.c_str() << " ... " << length_ << " bytes\n";
// Buffer as null terminated to be converted to string
buffer_.reset(new char[length_ + 1]);
buffer_[length_] = 0;
ifs.read(buffer_.get(), length_);
ifs.close();
}
std::size_t GetLength() {
return length_;
}
char* GetBuffer() {
return buffer_.get();
}
};
void GetImageFile(const std::string& image_file,
mx_float* image_data, int channels,
cv::Size resize_size, const mx_float* mean_data = nullptr) {
// Read all kinds of file into a BGR color 3 channels image
cv::Mat im_ori = cv::imread(image_file, cv::IMREAD_COLOR);
if (im_ori.empty()) {
std::cerr << "Can't open the image. Please check " << image_file << ". \n";
assert(false);
}
cv::Mat im;
resize(im_ori, im, resize_size);
int size = im.rows * im.cols * channels;
mx_float* ptr_image_r = image_data;
mx_float* ptr_image_g = image_data + size / 3;
mx_float* ptr_image_b = image_data + size / 3 * 2;
float mean_b, mean_g, mean_r;
mean_b = mean_g = mean_r = DEFAULT_MEAN;
mean_b = 103.06;
mean_g = 115.9;
mean_r = 123.15;
for (int i = 0; i < im.rows; i++) {
auto data = im.ptr<uchar>(i);
for (int j = 0; j < im.cols; j++) {
if (channels > 1) {
*ptr_image_b++ = static_cast<mx_float>(*data++) - mean_b;
*ptr_image_g++ = static_cast<mx_float>(*data++) - mean_g;
}
*ptr_image_r++ = static_cast<mx_float>(*data++) - mean_r;
}
}
}
// LoadSynsets
// Code from : https://github.com/pertusa/mxnet_predict_cc/blob/master/mxnet_predict.cc
std::vector<std::string> LoadSynset(const std::string& synset_file) {
std::ifstream fi(synset_file.c_str());
if (!fi.is_open()) {
std::cerr << "Error opening synset file " << synset_file << std::endl;
assert(false);
}
std::vector<std::string> output;
std::string synset, lemma;
while (fi >> synset) {
getline(fi, lemma);
output.push_back(lemma);
}
fi.close();
return output;
}
void PrintOutputResult(const std::vector<float>& data, const std::vector<std::string>& synset) {
if (data.size() != synset.size()) {
std::cerr << "Result data and synset size do not match!" << std::endl;
}
float best_accuracy = 0.0;
std::size_t best_idx = 0;
for (std::size_t i = 0; i < data.size(); ++i) {
std::cout << "Accuracy[" << i << "] = " << std::setprecision(8) << data[i] << std::endl;
if (data[i] > best_accuracy) {
best_accuracy = data[i];
best_idx = i;
}
}
std::cout << "Best Result: " << trim(synset[best_idx]) << " (id=" << best_idx << ", " <<
"accuracy=" << std::setprecision(8) << best_accuracy << ")" << std::endl;
}
void predict(PredictorHandle pred_hnd, const std::vector<mx_float> &image_data,
NDListHandle nd_hnd, const std::string &synset_file, int i) {
auto image_size = image_data.size();
// Set Input
//>>>>>>>>>>>>>>>>>>>> Problem code <<<<<<<<<<<<<<<<<<<<<<<
MXPredSetInput(pred_hnd, "data", image_data.data(), static_cast<mx_uint>(image_size));
// <<<<<<<<<<<<<<<<<<<<<<< Problem code <<<<<<<<<<<<<<<<<<<<<<<
// Do Predict Forward
MXPredForward(pred_hnd);
mx_uint output_index = 0;
mx_uint* shape = nullptr;
mx_uint shape_len;
// Get Output Result
MXPredGetOutputShape(pred_hnd, output_index, &shape, &shape_len);
std::size_t size = 1;
for (mx_uint i = 0; i < shape_len; ++i) { size *= shape[i]; }
std::vector<float> data(size);
MXPredGetOutput(pred_hnd, output_index, &(data[0]), static_cast<mx_uint>(size));
// Release NDList
if (nd_hnd) {
MXNDListFree(nd_hnd);
}
// Release Predictor
MXPredFree(pred_hnd);
// Synset path for your model, you have to modify it
auto synset = LoadSynset(synset_file);
// Print Output Data
PrintOutputResult(data, synset);
}
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cout << "No test image here." << std::endl
<< "Usage: ./image-classification-predict apple.jpg [num_threads]" << std::endl;
return EXIT_FAILURE;
}
std::string test_file(argv[1]);
int num_threads = 1;
if (argc == 3)
num_threads = std::atoi(argv[2]);
// Models path for your model, you have to modify it
std::string json_file = "../model/rfcn_dcn_chicken-0000.json";
std::string param_file = "../model/rfcn_dcn_chicken-0000.params";
std::string synset_file = "../model/synset.txt";
std::string nd_file = "../model/mean_224.nd";
BufferFile json_data(json_file);
BufferFile param_data(param_file);
// Parameters
int dev_type = 1; // 1: cpu, 2: gpu
int dev_id = 0; // arbitrary.
mx_uint num_input_nodes = 1; // 1 for feedforward
const char* input_key[1] = { "data" };
const char** input_keys = input_key;
// Image size and channels
int width = 1000;
int height = 562;
int channels = 3;
const mx_uint input_shape_indptr[2] = { 0, 4 };
const mx_uint input_shape_data[4] = { 1,
static_cast<mx_uint>(channels),
static_cast<mx_uint>(height),
static_cast<mx_uint>(width) };
if (json_data.GetLength() == 0 || param_data.GetLength() == 0) {
return EXIT_FAILURE;
}
auto image_size = static_cast<std::size_t>(width * height * channels);
// Read Mean Data
const mx_float* nd_data = nullptr;
NDListHandle nd_hnd = nullptr;
BufferFile nd_buf(nd_file);
if (nd_buf.GetLength() > 0) {
mx_uint nd_index = 0;
mx_uint nd_len;
const mx_uint* nd_shape = nullptr;
const char* nd_key = nullptr;
mx_uint nd_ndim = 0;
MXNDListCreate(static_cast<const char*>(nd_buf.GetBuffer()),
static_cast<int>(nd_buf.GetLength()),
&nd_hnd, &nd_len);
MXNDListGet(nd_hnd, nd_index, &nd_key, &nd_data, &nd_shape, &nd_ndim);
}
// Read Image Data
std::vector<mx_float> image_data(image_size);
GetImageFile(test_file, image_data.data(), channels, cv::Size(width, height), nd_data);
if (num_threads == 1) {
// Create Predictor
PredictorHandle pred_hnd;
MXPredCreate(static_cast<const char*>(json_data.GetBuffer()),
static_cast<const char*>(param_data.GetBuffer()),
static_cast<int>(param_data.GetLength()),
dev_type,
dev_id,
num_input_nodes,
input_keys,
input_shape_indptr,
input_shape_data,
&pred_hnd);
assert(pred_hnd);
predict(pred_hnd, image_data, nd_hnd, synset_file, 0);
} else {
// Create Predictor
std::vector<PredictorHandle> pred_hnds(num_threads, nullptr);
MXPredCreateMultiThread(static_cast<const char*>(json_data.GetBuffer()),
static_cast<const char*>(param_data.GetBuffer()),
static_cast<int>(param_data.GetLength()),
dev_type,
dev_id,
num_input_nodes,
input_keys,
input_shape_indptr,
input_shape_data,
pred_hnds.size(),
pred_hnds.data());
for (auto hnd : pred_hnds)
assert(hnd);
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; i++)
threads.emplace_back(predict, pred_hnds[i], image_data, nd_hnd, synset_file, i);
for (int i = 0; i < num_threads; i++)
threads[i].join();
}
printf("run successfully\n");
return EXIT_SUCCESS;
}

portaudio only taking one sample?

I am currently working with portaudio with an application that records, and I seem to have some issues collecting the samples. From what I can see is only one sample being stored, and the callback is only being called once, and that is it, even though the variable NUM_OF_SECONDS is set to 30 seconds.
I currently running out of ideas of what I can test, and how I can debug this, so I've come here, any suggestions to how I can debug my problem?
Here is the code:
main.cpp:
#include <record.h>
int main()
{
record somethis;
somethis.start_record();
return 0;
}
record.h
#pragma once
#include <iostream> // Functionality: COUT
#include "portaudio.h"
#include <stdio.h>
#include <stdlib.h>
#include <chrono> //Functionality: Sleep
#include <thread> //Functionality: Sleep
#include <algorithm> //Functionality: fill_n
#define SAMPLE_RATE (44100)
typedef float SAMPLE;
#define NUM_SECONDS 30
#define NUM_CHANNELS 2
#define SAMPLE_SILENCE 0.0f
#define PA_SAMPLE_TYPE paFloat32
#define FRAMES_PER_BUFFER (512)
#define TRUE (1==1)
#define FALSE (!TRUE)
#define WRITE_TO_FILE TRUE
typedef struct
{
int frameIndex;
int maxFrameindex;
SAMPLE *recordedSamples;
}
paTestData;
class record {
public:
record();
void start_record();
private:
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData);
static int recordCallbackSub(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
auto pThis = reinterpret_cast<record*>(userData); // get back the this pointer.
return pThis->recordCallback( inputBuffer, outputBuffer,framesPerBuffer, timeInfo,statusFlags, nullptr);
}
};
record.cpp
#include "record.h"
record::record()
{
std::cout << "Record object made" << std::endl;
std::cout << "Portaudio Version: " << Pa_GetVersion() << std::endl;
this->data.maxFrameindex = this->totalFrames = NUM_SECONDS * SAMPLE_RATE;
this->data.frameIndex = 0;
this->numSamples = this->totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
this->data.recordedSamples = new SAMPLE[numSamples]; /* From now on, recordedSamples is initialised. */
if( this->data.recordedSamples == NULL )
{
std::cout << "Could not allocate record array" << std::endl;
exit(1);
}
for(int i=0; i<numSamples; i++ )
{
this->data.recordedSamples[i] = 0;
}
int err = Pa_Initialize();
if( err == paNoError )
{
std::cout << "No error in init" << std::endl;
std::cout << "PortAudio init: "<< Pa_GetErrorText( err ) << std::endl;
}
else
{
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
exit(1);
}
this->inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (this->inputParameters.device == paNoDevice) {
std::cout << "Error: No default input device" << std::endl;
exit(1);
}
this->inputParameters.channelCount = 1; /* stereo input */
this->inputParameters.sampleFormat = PA_SAMPLE_TYPE;
this->inputParameters.suggestedLatency = Pa_GetDeviceInfo( this->inputParameters.device )->defaultLowInputLatency;
this->inputParameters.hostApiSpecificStreamInfo = NULL;
std::cout << "Device name: " <<Pa_GetDeviceInfo(this->inputParameters.device)->name << std::endl;
std::cout << "Max inputChannels: " <<Pa_GetDeviceInfo(this->inputParameters.device)->maxInputChannels << std::endl;
}
int record::recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
std::cout << "Callback called" << std::endl;
this->data = (paTestData&) userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &this->data.recordedSamples[this->data.frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = this->data.maxFrameindex - this->data.frameIndex;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
//(void) userData;
if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if( inputBuffer == NULL )
{
for(int i=0; i<framesToCalc; i++ )
{
*wptr++ = SAMPLE_SILENCE; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
for(int i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
}
this->data.frameIndex += framesToCalc;
return finished;
}
void record::start_record()
{
err = Pa_OpenStream(
&this->stream,
&this->inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
&record::recordCallbackSub,
this );
if( err != paNoError )
{
std::cout << "Something wrong - open_stream check" << std::endl;
std::cout << "PortAudio error: "<< Pa_GetErrorText( err ) << std::endl;
exit(1);
}
this->err = Pa_StartStream( this->stream );
if( err != paNoError )
{
std::cout << "Something wrong in stream check" << std::endl;
std::cout << "PortAudio error: "<< Pa_GetErrorText( err ) << std::endl;
exit(1);
}
std::cout << "Waiting for playback to finish" << std::endl;
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(1000);
printf("index = %d\n", this->data.frameIndex ); fflush(stdout);
}
if( err < 0 )
{
std::cout << "error check with isStreamActive - something wrong" << std::endl;
std::cout << "PortAudio error: "<< Pa_GetErrorText( err ) << std::endl;
exit(1);
}
err = Pa_CloseStream( stream );
if( err != paNoError )
{
std::cout << "error check with close_stream- something wrong" << std::endl;
std::cout << "PortAudio error: "<< Pa_GetErrorText( err ) << std::endl;
exit(1);
}
std::cout << "Number of entries: " << sizeof(this->data.recordedSamples)/sizeof(this->data.recordedSamples[0]) << std::endl;
/* Measure maximum peak amplitude. */
max = 0;
average = 0.0;
for(int i=0; i<numSamples; i++ )
{
val = this->data.recordedSamples[i];
std::cout << "i: " << i << " : "<< val << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if( val < 0 ) val = -val; /* ABS */
if( val > max )
{
max = val;
}
average += val;
}
average = average / (double)numSamples;
std::cout<<"sample max amplitude = " << max << std::endl;
std::cout<<"sample average = " << average << std::endl;
if (WRITE_TO_FILE)
{
FILE *fid;
fid = fopen("recorded.wav", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
std::cout << "Everythin done!" << std::endl;
}
Update:
I've from some debugging notices that the callback is only being called once, and after it returns, becomes the stream inactive, hence making the it impossible to make calls to the callback function. Why does the stream become inactive?
Your first callback
static int recordCallbackSub(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
auto pThis = reinterpret_cast<record*>(userData); // get back the this pointer.
return pThis->recordCallback( inputBuffer, outputBuffer,framesPerBuffer, timeInfo,statusFlags, nullptr);
}
calls your second callback
int record::recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
std::cout << "Callback called" << std::endl;
this->data = (paTestData&) userData;
....
}
with the userData parameter set to nullptr. You then cast the nullptr into a paTestData& and set your data member variable to the result, which I suspect you didn't intend to do.
Delete the this->data = (paTestData&) userData; line.

Getting a "vector subscript out of range" error when passing a vector into a function: c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write a c++ program that assembles MIPS instructions. While debugging, it keeps throwing an error at line 74 of my main:
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
my main is here:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <memory>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
#include "exceptions.h"
#include "lexer.h"
#include "util.h"
#include "assembler.h"
std::string read_file(const std::string& name) {
std::ifstream file(name);
if (!file.is_open()) {
std::string error = "Could not open file: ";
error += name;
throw std::runtime_error(error);
}
std::stringstream stream;
stream << file.rdbuf();
return std::move(stream.str());
}
int main(int argc, char** argv) {
// Adjusting -- argv[0] is always filename.
--argc;
++argv;
if (argc == 0) {
std::cerr << "Need a file" << std::endl;
return 1;
}
assembler myassembler;
for (int i = 0; i < argc; ++i) {
std::string asmName(argv[i]);
if (!util::ends_with_subseq(asmName, std::string(".asm"))) {
std::cerr << "Need a valid file name (that ends in .asm)" << std::endl;
std::cerr << "(Bad name: " << asmName << ")" << std::endl;
return 1;
}
// 4 is len(".asm")
auto length = asmName.size() - string_length(".asm");
std::string baseName(asmName.begin(), asmName.begin() + length);
std::string objName = baseName + ".obj";
try {
auto text = read_file(asmName);
try {
auto lexed = lexer::analyze(text); // Parses the entire file and returns a vector of instructions
for (int i =0; i < (int)lexed.size(); i++){
if(lexed[i].labels.size() > 0) // Checking if there is a label in the current instruction
std::cout << "label = " << lexed[i].labels[0] << "\n"; // Prints the label
std::cout<< "instruction name = " << lexed[i].name<< "\n"; // Prints the name of instruction
std::cout << "tokens = ";
std::vector<lexer::token> tokens = lexed[i].args;
for(int j=0; j < (int)tokens.size(); j++){ // Prints all the tokens of this instruction like $t1, $t2, $t3
if (tokens[j].type == lexer::token::Integer)
std::cout << tokens[j].integer() << " ";
else
std::cout << tokens[j].string() << " ";
}
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
myassembler.p();
std::cout << "\n\n\n";
}
} catch(const bad_asm& e) {
std::stringstream error;
error << "Cannot assemble the assembly code at line " << e.line;
throw std::runtime_error(error.str());
} catch(const bad_label& e) {
std::stringstream error;
error << "Undefined label " << e.what() << " at line " << e.line;
throw std::runtime_error(error.str());
}
} catch (const std::runtime_error& err) {
std::cout << err.what() << std::endl;
return 1;
}
}
/*getchar();*/
return 0;
}
assembler.h:
#include "lexer.h"
#include <fstream>
#include <vector>
#include <string>
struct symbol
{
std::string label = "";
int slinenum;
};
struct relocation
{
std::string instruct = "";
std::string label = "";
int rlinenum;
int rt = 0;
int rs = 0;
};
struct opcode
{
std::string instruct = "";
int opc = 0;
bool isloadstore = false;
int extType = 0;
bool isbranch = false;
};
struct function
{
std::string instruct = "";
int funct = 0;
bool isjr = false;
bool isshift = false;
};
struct regs
{
std::string name;
int num;
};
enum instrtype
{
R, I, neither
};
class assembler
{
public:
assembler();
void oinit(void);
void finit(void);
void rinit(void);
void printToFile(std::fstream &file);
void savesymb(std::string label, int line);
void saverel(std::string instr, std::string label, int line, int rt, int rs);
std::vector<int> formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
int formatr(std::string instr, lexer::token toke, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, int line);
int findnum(std::string regname);
void add(std::string label, std::string instr, const std::vector<lexer::token> &tokens, int linen);
void secAdd(void);
int rassemble(std::string instr, int rd, int rs, int rt, int shamt);
int iassemble(std::string instr, int rt, int rs, int imm);
void p();
private:
std::vector<int> results;
std::vector<symbol> symbtable;
std::vector<relocation> reloctable;
std::vector<opcode> ops;
std::vector<function> functions;
std::vector<regs> registers;
instrtype type = neither;
};
and assembler.cpp:
// ECE 2500
// Project 1: myAssembler
// assembler.cpp
// Sheila Zhu
#include "lexer.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "assembler.h"
assembler::assembler()
{
oinit();
finit();
rinit();
}
void assembler::oinit()
{
opcode myop;
myop.instruct = "addi";
myop.opc = 8;
myop.extType = 1;
ops.push_back(myop);
// more of the same
}
void assembler::finit()
{
function myfunc;
myfunc.instruct = "add";
myfunc.funct = 32;
functions.push_back(myfunc);
// more of the same
}
void assembler::rinit()
{
regs myreg;
myreg.name = "$zero";
myreg.num = 0;
registers.push_back(myreg);
//more of the same
}
void assembler::printToFile(std::fstream &file)
{
for (int i = 0; i < (int)results.size(); i++)
file << results.at(i) << std::endl;
}
void assembler::savesymb(std::string label, int line)
{
symbol symb;
symb.label = label;
symb.slinenum = line * 4;
symbtable.push_back(symb);
}
void assembler::saverel(std::string instr, std::string label, int line, int rt, int rs)
{
relocation re;
re.instruct = instr;
re.label = label;
re.rlinenum = line;
re.rt = rt;
re.rs = rs;
}
int assembler::findnum(std::string regname)
{
for (int i = 0; i < (int)registers.size(); i++)
{
if (regname == registers.at(i).name)
return registers.at(i).num;
}
return -1;
}
std::vector<int> assembler::formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rd = 0, rs = 0, rt = 0, shamt = 0;
std::vector<int> x;
function currf;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
currf = functions.at(i);
}
try
{
if (currf.isshift)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
shamt = toke3.integer();
if (shamt < 0)
throw 3;
}
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke3.string());
if (rt == -1)
throw 2;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else if (e == 2)
std::cerr << "Invalid register name in line " << line << std::endl;
else
std::cerr << "Shift amount cannot be negative in line " << line << std::endl;
}
x.push_back(rd);
x.push_back(rs);
x.push_back(rt);
x.push_back(shamt);
return x;
}
int assembler::formatr(std::string instr, lexer::token toke, int line)
{
int rs = 0;
try
{
if (toke.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke.string());
if (rs == -1)
throw 2;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
return rs;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rt = 0, rs = 0, imm = 0;
std::vector<int> x;
opcode currop;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
currop = ops.at(i);
}
try
{
if (currop.isbranch)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
saverel(instr, toke3.string(), line, rt, rs);
}
else if (currop.isloadstore)
{
if ((instr == "lbu") || (instr == "sb"))
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + (0xFF << 8) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
else
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
}
else
{
if ((instr == "andi") || (instr == "ori"))
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
if (toke3.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke3.integer();
}
else
throw 1;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
x.push_back(rt);
x.push_back(rs);
x.push_back(imm);
return x;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, int line)
{
int rt = 0, imm = 0;
std::vector<int> rval;
try
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::String)
throw 1;
else
imm = toke2.integer();
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
rval.push_back(rt);
rval.push_back(imm);
return rval;
}
void assembler::add(std::string label, std::string instr, const std::vector<lexer::token> &token, int linen)
{
int assembled = 0, rd = 0, rt = 0;
std::vector<int> argh;
int arg;
if (label.length() > 0)
savesymb(label, linen);
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
type = R;
}
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
type = I;
}
if (type == R)
{
try
{
if (instr == "jr")
{
if ((int)token.size() == 1)
{
arg = formatr(instr, token.at(0), linen);
assembled = rassemble(instr, rd, arg, rt, 0);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formatr(instr, token.at(0), token.at(2), token.at(3), linen);
assembled = rassemble(instr, argh[0], argh[1], argh[2], argh[3]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong number of arguments at line " << linen << std::endl;
}
}
else if (type == I)
{
try
{
if (instr == "lui")
{
if ((int)token.size() == 2)
{
argh = formati(instr, token.at(0), token.at(1), linen);
assembled = iassemble(instr, argh[0], 0, argh[1]);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formati(instr, token.at(0), token.at(1), token.at(2), linen);
assembled = iassemble(instr, argh[0], argh[1], argh[2]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cout << "Wrong number of arguments at line " << linen << std::endl;
}
}
else
std::cerr << "Instruction not recognized at line " << linen << std::endl;
results.push_back(assembled);
}
void assembler::secAdd(void)
{
std::vector<int>::iterator iter = results.begin();
for (int i = 0; i < (int)reloctable.size(); i++)
{
for (unsigned int j = 0; j < symbtable.size(); j++)
{
if (reloctable.at(i).label == symbtable.at(j).label)
{
int assembled = 0;
iter += (reloctable.at(i).rlinenum / 4);
for (unsigned int k = 0; k < ops.size(); k++)
{
if (reloctable.at(i).instruct == ops.at(k).instruct)
type = I;
}
if (type == I)
assembled = iassemble(reloctable.at(i).instruct, reloctable.at(i).rt, reloctable.at(i).rs, symbtable.at(i).slinenum);
else
std::cerr << "Instruction not recognized at line " << reloctable.at(i).rlinenum << std::endl;
results.erase(iter);
results.insert(iter, assembled);
}
}
}
}
int assembler::rassemble(std::string instr, int rd, int rs, int rt, int shamt)
{
int func = 0;
int code = 0;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
{
func = functions.at(i).funct;
break;
}
else
{
if (i == (functions.size() - 1))
return -1;
}
}
code = (rs << 21) + (rt << 16) + (rd << 11) + (shamt << 6) + func;
return code;
}
int assembler::iassemble(std::string instr, int rt, int rs, int imm)
{
int op = 0;
int code = 0;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
{
op = ops.at(i).opc;
break;
}
else
{
if (i == (ops.size() - 1))
return -1;
}
}
code = (op << 26) + (rs << 21) + (rt << 16) + imm;
return code;
}
void assembler::p()
{
for (int i = 0; i < (int)results.size(); i++)
std::cout << results.at(i) << " ";
std::cout << std::endl;
}
When debugging, the tokens parameter triggers the error, and the this pointer in the vector code shows that the vector size changes to 0 at these lines:
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() <= _Pos)
What exactly is happening?
Sorry if my formatting is bad/wrong, etc., and please let me know if I should make any edits/provide more code.
Thanks in advance.
The error is caused by accessing by index vector element that does not exist.
In you case lexed[i] should be valid. So, the only possible issue may be with empty labels vector. Validate this vector before accessing its elements, for example
myassembler.add(lexed[i].labels.empty() ? "" : lexed[i].labels[0],
lexed[i].name, tokens, i);
Actually there is one more bug for very large lexed arrays when integer index may overflow. You should not cast result of .size() to int. Instead proper type should be used for i:
for (size_t i = 0; i < lexed.size(); i++)

SDLNet: How to define the server IP address

I already succeeded when trying to connect a client to a server. But the server was using the loopback ip address. How is it possible to make a server using SDLNet so that i can access it from any computer that is connected to any network?
The problem is the code because I don't find any place where I can define another IP address for the server...
Here is the code for the server:
#include "Link\SDL\include\SDL.h"
#include "Link\SDL\include\SDL_net.h"
#include <iostream>
#include <vector>
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
int curid=2;
int playernum = 0;
char data[1400];
bool running=true;
SDL_Event event;
IPaddress ip;
SDLNet_ResolveHost(&ip,NULL,1234);
SDLNet_SocketSet sockets=SDLNet_AllocSocketSet(30); //max player
std::vector<TCPsocket> socketsvector;
TCPsocket server=SDLNet_TCP_Open(&ip);
while(running)
{
while(SDL_PollEvent(&event))
{
if(event.type==SDL_QUIT || event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE)
{
running=false;
break;
}
}
TCPsocket tmpsocket=SDLNet_TCP_Accept(server);
if(tmpsocket)
{
if(playernum<30)
{
SDLNet_TCP_AddSocket(sockets,tmpsocket);
socketsvector.push_back(tmpsocket);
sprintf(data,"0 %d \n",curid);
curid++;
playernum++;
std::cout << "new connection. ID: " << curid << std::endl;
}
else
{
sprintf(data,"3 \n"); //server is full
}
SDLNet_TCP_Send(tmpsocket,data,strlen(data)+1);
}
while(SDLNet_CheckSockets(sockets,0) > 0)
{
for(int i=0;i<socketsvector.size();i++)
{
if(SDLNet_SocketReady(socketsvector[i])==1)
{
SDLNet_TCP_Recv(socketsvector[i],data,1400);
int num=data[0]-'0';
int j=1;
while(data[j]>='0' && data[j]<='9')
{
num*=10;
num+=data[j]-'0';
j++;
}
if(num==1)
{
for(int k=0;k<socketsvector.size();k++)
{
if(k==i)
continue;
SDLNet_TCP_Send(socketsvector[k],data,strlen(data)+1);
}
}else if(num==2)
{
for(int k=0;k<socketsvector.size();k++)
{
if(k==i)
continue;
SDLNet_TCP_Send(socketsvector[k],data,strlen(data)+1);
}
SDLNet_TCP_DelSocket(sockets,socketsvector[i]);
SDLNet_TCP_Close(socketsvector[i]);
socketsvector.erase(socketsvector.begin()+i);
playernum--;
std::cout << "connection closed..." << std::endl;
std::cout << playernum << " players in server" << std::endl;
}
}
}
}
//SDL_Delay(30);
}
SDLNet_TCP_Close(server);
SDLNet_FreeSocketSet(sockets);
SDLNet_Quit();
SDL_Quit();
return 0;
}
Ok, and here is the code for the client...
class network{
private:
SDLNet_SocketSet sockets;
TCPsocket connection;
char data[1400];
public:
network(const char* ip);
~network();
void send(Player* p);
void receive(std::vector<Enemy*>& enemies, Player* p); //std::vector<unsigned int>& f,std::vector<enemy*>& enemies,std::vector<weapon*> weapons,player* p
void closeConnection();
};
network::network(const char* ipaddress)
{
SDLNet_Init();
IPaddress ip;
if(SDLNet_ResolveHost(&ip,ipaddress,1234)==-1)
std::cout << "error while resolving the host (bad ip?)" << std::endl;
connection=SDLNet_TCP_Open(&ip);
sockets=SDLNet_AllocSocketSet(1);
if(sockets==NULL)
std::cout << "error while connecting (bad ip?)" << std::endl;
SDLNet_TCP_AddSocket(sockets,connection);
}
void network::closeConnection()
{
SDLNet_TCP_Send(connection,"2 \n",4); //close with the server
}
network::~network()
{
SDLNet_TCP_Close(connection);
SDLNet_FreeSocketSet(sockets);
SDLNet_Quit();
}
void network::send(Player* p)
{
vector3d vec=p->cam.getVector();
//1 curframe position rotation lookdirection health curweaponnum
sprintf(data,"1 %d %f %f %f %f %f %f \n",p->id, p->cam.getLocation().x,p->cam.getLocation().y,p->cam.getLocation().z,vec.x,vec.y,vec.z);
int size=0;
int len=strlen(data)+1;
//SDLNet_TCP_Send(connection,data,len);
while(size<len)
{
size+=SDLNet_TCP_Send(connection,data+size,len-size);
}
}
void network::receive(std::vector<Enemy*>& enemies, Player* p) //std::vector<unsigned int>& f,std::vector<enemy*>& enemies,std::vector<weapon*> weapons,player* p
{
SDLNet_CheckSockets(sockets,10);
if(SDLNet_SocketReady(connection))
{
int tmp,num;
int offset=0;
do
{
offset=SDLNet_TCP_Recv(connection,(char*)data+(offset),1400);
if(offset<=0)
return;
}while(data[strlen(data)-1]!='\n');
sscanf(data,"%d %d",&num,&tmp);
//cout << num << " " << tmp << endl;
cout << data << endl;
int i=0;
if(num == 0)
{
p->setId(tmp);
}
else if(num==1)
{
bool NewEnemy = true;
for(i=0;i<enemies.size();i++)
{
if(enemies[i]->id == tmp)
{
int nothing;
sscanf(data,"1 %d %f %f %f %f %f %f \n",&nothing, &(enemies[i]->position.x),&(enemies[i]->position.y),&(enemies[i]->position.z),&(enemies[i]->rotation.x),&(enemies[i]->rotation.y),&(enemies[i]->rotation.z));
NewEnemy = false;
break;
}
}
if(NewEnemy == true && tmp != 0)
{
std::cout << "pusing new enemy" << std::endl;
enemies.push_back(new Enemy(tmp));
}
}
else if(num == 2)
{
for(int k = 0; k < enemies.size(); k++)
{
if(enemies[k]->id == tmp)
{
enemies.erase(enemies.begin() + k);
}
}
}
else if(num == 3)
{
std::cout << "Could not connect. Server is full." << std::endl;
}
}
}
If you can see, I type the IP address for the client when the program starts. But the only value that works is the loopback address.