Taking input parameter in C++ Win32 console application - visual-c++

I generated C++ shared library in MATLAB and integrated it in Win32 console application in C++. I have to call this console application from PHP.It has 5 inputs which should be passed from php. When I run the application giving the input parameters it runs. The code which runs properly is as below:
#include "stdafx.h"
#include "shoes_sharedlibrary.h"
#include <iostream>
#include <string.h>
#include "mex.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
/* Call the MCR and library initialization functions */
if( !mclInitializeApplication(NULL,0) )
{
exit(1);
}
if (!shoes_sharedlibraryInitialize())
{
exit(1);
}
mwArray img= "C:/Users/aadbi.a/Desktop/dressimages/T1k5aHXjNqXXc4MOI3_050416.jpg";
double wt1 = 0;
mwArray C(wt1);
double wt2=0;
mwArray F(wt2);
double wt3=0;
mwArray T(wt3);
double wt4=1;
mwArray S(wt4);
test_shoes(img,C,F,T,S);
shoes_sharedlibraryTerminate();
mclTerminateApplication();
return 0;
}
The C,F,T,S are value between 0 and 1. How can I pass the input arguments as it is in _TCHAR*?How can I convert the _TCHAR* into decimal or double and again converting that into mwArray to pass into test_shoes. The test_shoes only takes mwArray as input.
The test_shoes function definition is:
void MW_CALL_CONV test_shoes(const mwArray& img_path, const mwArray& Wcoarse_colors,
const mwArray& Wfine_colors, const mwArray& Wtexture, const
mwArray& Wshape)
{
mclcppMlfFeval(_mcr_inst, "test_shoes", 0, 0, 5, &img_path, &Wcoarse_colors, &Wfine_colors, &Wtexture, &Wshape);
}

You can convert the command line string arguments to double using the atof() function from stdlib.h. As I see you are using the TCHAR equivalents, there is a macro that wraps the correct call for UNICODE and ANSI builds, so you can do something like this (assuming your command line arguments are in the correct order)
#include "stdafx.h"
#include "shoes_sharedlibrary.h"
#include <iostream>
#include <string.h>
#include "mex.h"
#include <stdlib.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
// ... initial code
// convert command line arguments to doubles ...
double wt1 = _tstof(argv[1]);
mwArray C(wt1);
double wt2 = _tstof(argv[2]);
mwArray F(wt2);
double wt3 = _tstof(argv[3]);
mwArray T(wt3);
// ... and so on ....
}
Note that argv[0] will contain the name of your program as specified on the command line, so the arguments begin at argv[1]. Then your command line can be something like:
yourprog.exe 0.123 0.246 0.567 etc.

Related

How to insert distance sensor in Kuka robot in webots software

I am trying to add a distance sensor to a kuka robot in webots software KUKA robot that has no field called children but I added the distance sensor in bodyslot field now the sensor is reading nan all the time
#include <webots/keyboard.h>
#include <webots/robot.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <webots/distance_sensor.h>
#define TIME_STEP 32
int main(int argc, char **argv) {
wb_robot_init();
//////////////////////////////
WbDeviceTag ps[1];
char ps_names[1][3] = {"DS"};
ps[0] = wb_robot_get_device(ps_names[0]);
wb_distance_sensor_enable(ps[0], TIME_STEP);
////////////////////////////////
// read sensors outputs
double ps_values;
ps_values = wb_distance_sensor_get_value(ps[0]);
//////////////////////////////////////////////////////////
while (true) {
step();
printf ("\n %f \n", ps_values);
//while (ps_values > 80){
base_forwards_increment();
//}
// base_backwards_increment();
}
wb_robot_cleanup();
return 0;
}
enter image description here
To find a way to add a distance sensor to kuka robot

ICU4C austrdup function

I'm trying to run the code demo for ICU4C bellow, and getting
warning: implicit declaration of function 'austrdup'
which subsequently generate an error. I understand that this is due to the missing imported library that contains 'austrdup' function, and have been looking at the source code to guess which one it is, but no luck. Does anyone have any idea which one should be imported?
#include <unicode/umsg.h>
#include <unicode/ustring.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
UChar* str;
UErrorCode status = U_ZERO_ERROR;
UChar *result = NULL;
UChar pattern[100];
int32_t resultlength, resultLengthOut, i;
double testArgs[] = { 100.0, 1.0, 0.0};
str=(UChar*)malloc(sizeof(UChar) * 10);
u_uastrcpy(str, "MyDisk");
u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number,integer} files}");
for(i=0; i<3; i++){
resultlength=0;
resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, testArgs[i], str);
if(status==U_BUFFER_OVERFLOW_ERROR){ //check if output truncated
status=U_ZERO_ERROR;
resultlength=resultLengthOut+1;
result=(UChar*)malloc(sizeof(UChar) * resultlength);
u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, testArgs[i], str);
}
printf("%s\n", austrdup(result) ); //austrdup( a function used to convert UChar* to char*)
free(result);
}
return 0;
}
austrdup is not an official ICU method. It's only used by tests in ICU and defined in icu4c/source/test/cintltst/cintltst.h and implemented in icu4c/source/test/cintltst/cintltst.c. It is bascially just a wrapper around u_austrcpy.

Inter process communication using FIFO

Client server must pass to the Server process a filename and the Server process must return the number of lines in the file. My problem is that the received variable only contains 6 characters of the filename and it ends up by throwing segmentation fault dump core error. Do you know why this happens? This is my code:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(){
int fd1,fd2;
const char *fifo1="./fifo1Channel";
const char *fifo2="./fifo2Channel";
mkfifo(fifo1,0666);
mkfifo(fifo2,0666);
char filename[30];
printf("Give me a filename:\n");
fgets(filename,30,stdin);
strtok(filename,"\n");
int pid=fork();
if(pid>0){
char received[30], ch;
FILE *fp;
fd1=open(fifo1, O_RDONLY);
read(fd1,received,strlen(received));
close(fd1);
printf("From server process:%s\n",received);
fp=fopen(received,"r");
int nrOfLines=0;
for(ch=getc(fp);ch!=EOF;ch=getc(fp))
if(ch=='\n')
nrOfLines++;
fd2=open(fifo2, O_WRONLY);
write(fd2,&nrOfLines,sizeof(nrOfLines));
close(fd2);
return 0;
}
if(pid==0){
int receivedNumber;
fd1=open(fifo1,O_WRONLY);
write(fd1,filename,strlen(filename));
close(fd1);
fd2=open(fifo2,O_RDONLY);
read(fd2,&receivedNumber,sizeof(receivedNumber));
close(fd2);
printf("From client process: %d\n",receivedNumber);
return 0;
}
return 0;
}
I think the problem was in server process. I replaced strlen(received) with 30, the maximum number of characters of filename, in function read and it works now!

Problems when reading integers with scanf

I know that it might be a stupid question but can you tell me why the following patch of code fails? I see nothing wrong. I am trying to read integers using scanf. I have included the necessary library, but when I run the program it crashes after I read the first s. Thank you.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
int main()
{
int n, x;
scanf("%d", &n); scanf("%d", &x);
vector< pair<int, int> > moments;
for(int i = 0; i < n; ++i)
{
int f, s;
scanf("%d", &f);
scanf("%d", &s );
moments[i].first = f;
moments[i].second = s;
}
return 0;
}
That is not the way to assign values to moments since moments[i] does not yet exist. Try:
pair<int, int> thing;
thing = make_pair(f,s);
moments.push_back(thing);
instead of your assignements to moments elements.

Cuda - printing string from object in __global__ function

I am new to CUDA and I am getting a strange error. I want to print a string from a passed object and I get the error "calling host function from global function is not allowed" and I don't know why. But if I want to print an integer (changing get method to return sk1), everything works fine. Here is the code:
class Duomenys {
private:
string simb;
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): simb(""), sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys::Duomenys(string simb1, int sk11, double sk21)
: simb(simb1), sk1(sk11), sk2(sk21) {}
__device__ __host__ string Duomenys::get(){
return simb;
}
};
And here I am calling Duomenys::get from __global__ function:
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.get());
}
EDIT: I am trying to read data from a file and print it in a global function. In this code I am trying read all data and print just one object to see if everything works. This is the error I'm getting:
calling a __host__ function("std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string") from a __global__ function("Vec_add") is not allowed
Code:
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
class Duomenys {
private:
string simb;
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): simb(""), sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys::Duomenys(string simb1, int sk11, double sk21)
: simb(simb1), sk1(sk11), sk2(sk21) {}
__device__ __host__ string Duomenys::print()
{
stringstream ss;
ss << left << setw(10) << simb << setw(10) << sk1 << setw(10) << sk2;
return ss.str();
}
};
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.print());
}
/* Host code */
int main(int argc, char* argv[]) {
setlocale (LC_ALL,"");
vector<Duomenys> vienas;
vector<vector<Duomenys>> visi;
//data reading to vector "vienas" (it works without any errors)
Duomenys *darr;
const size_t sz = size_t(2) * sizeof(Duomenys);
cudaMalloc((void**)&darr, sz);
Vec_add<<<1, 1>>>(visi[0].at(0));
cudaDeviceSynchronize();
cudaMemcpy(darr, &visi[0].at(0), sz, cudaMemcpyHostToDevice);
return 0;
}
Your problem is not with printf function, but with string data type. You cannot use the C++ string type in a kernel. See related question here: Can we use the string data type in C++ within kernels
Why would you pass a string object to printf when the %s format specifier is expecting something else? When I try to do that in ordinary host code, I get warnings about "passing non-POD types through ellipsis (call will abort at runtime)". Note that this problem has nothing to do with CUDA.
But beyond that issue, presumably you're getting string from the C++ standard library. (It's better if you show a complete reproducer code, then I don't have to guess at where you're getting things or what you are including.)
If I get string as follows:
#include <string>
using namespace std;
Then I am using a function defined in the C++ Standard Library. CUDA supports the C++ language (mostly) but does not necessarily support usage of C++ libraries (or C libraries, for that matter) in device code. Libraries are (usually) composed of (at least some) compiled code (such as allocators, in this case), and this code has been compiled for CPUs, not for the GPU. When you try to use such a CPU compiled routine (e.g. an allocator associated with the string class) in device code, the compiler will bark at you. If you include the complete error message in the question, it will be more obvious specifically what (compiled-for-the-host) function is actually the issue.
Use a standard C style string instead (i.e. char[] and you will be able to use it directly in printf.
EDIT: In response to a question in the comments, here is a modified version of the code posted that demonstrates how to use an ordinary C-style string (i.e. char[]) and print from it in device code.
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#define STRSZ 32
using namespace std;
class Duomenys {
private:
char simb[STRSZ];
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys(char *simb1, int sk11, double sk21)
: sk1(sk11), sk2(sk21) {}
__device__ __host__ char * print()
{
return simb;
}
__device__ __host__ void store_str(const char *str)
{
for (int i=0; i< STRSZ; i++)
simb[i] = str[i];
}
};
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.print());
}
/* Host code */
int main(int argc, char* argv[]) {
string host_string("hello\n");
setlocale (LC_ALL,"");
vector<Duomenys> vienas(3);
vienas[0].store_str(host_string.c_str());
vector<vector<Duomenys> > visi(3);
visi[0] = vienas;
//data reading to vector "vienas" (it works without any errors)
Duomenys *darr;
const size_t sz = size_t(2) * sizeof(Duomenys);
cudaMalloc((void**)&darr, sz);
Vec_add<<<1, 1>>>(visi[0].at(0));
cudaDeviceSynchronize();
cudaMemcpy(darr, &(visi[0].at(0)), sz, cudaMemcpyHostToDevice);
return 0;
}
Note that I didn't try to understand your code or fix everything that looked strange to me. However this should demonstrate one possible approach.

Resources