Working with vector values in C++ CLI - visual-c++

Here is my header file in Visual C++ Express 2010 (note the last line):
/* custom class header to communicate with LynxMotion robot arm */
using namespace System;
using namespace System::IO::Ports;
public ref class LynxRobotArm
{
public:
LynxRobotArm();
~LynxRobotArm();
void connectToSerialPort(String^ portName, int baudRate);
void disconnectFromSerialPort();
void setCurrentPosition(int channel, int position);
int getCurrentPosition(int channel);
void moveToPosition(int channel, int position);
private:
void initConnection();
SerialPort^ serialPort;
array<String^> ^serialPortNames;
String^ portName;
int baudRate;
std::vector<int> *currentPosition;
};
I try to assign a value to the vector by using this function;
void LynxRobotArm::setCurrentPosition(int channel, int position)
{
currentPosition[channel] = position;
}
The compiler gives me an error C2679:
binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
I looked up at MSDN and they say:
To use the operator, you must overload it for the specified type or define a conversion to a type for which the operator is defined.
I tried using currentPosition.at(channel) = position but it did not make a difference.
I am stuck... quite new to pointers, noted that using std::vector<int> currentPosition; instead of std::vector<int> *currentPosition; does not compile.
How should my set-function work? (will try getter afterwards..)

Related

How to keep parameter refness when passing to template taking variadic parameters?

The following breaks on the last line of main():
import std.stdio, std.traits;
void main(){
void test(ref int){}
void delegate(Parameters!test) works = &test;
template broken(Args...){
void delegate(Args) broken;
}
broken!(Parameters!test) = &test; // Error: cannot implicitly convert expression &test of type void delegate(ref int _param_0) pure nothrow #nogc #safe to void delegate(int)
}
Is this intended? If so, how to work around it?

VC++ 2010 can access class variable vector of struct from Main() but not from class function

I have written a header file with one basic data structure.
ProdList.h
#ifndef LISTOFITEMS_H
#define LISTOFITEMS_H
struct ListOfItems
{
public:
std::string fdcustid;
std::string fdstkid;
std::string fdordisquantity;
std::string fdordsstatus; // <> 'H'
std::string fdordhtype; // <> 'A'
};
#endif /* GRANDFATHER_H */
now that I have a data structure I include it in the class definition and use the data structure "ListOfItems" in the class "ProdContainer".
ProdContainer.h
#include "ProdList.h"
class ProdContainer
{
public:
ProdContainer(void);
~ProdContainer(void);
static void SetNumberOfElements(int Elements);
std::vector<ListOfItems> Items;
}
now when i write the following in Main.
int _tmain(int argc, _TCHAR* argv[])
{
ProdContainer myobject;
myobject.Items.resize(12);
printf("The size of Items is %i \n", myobject.Items.size());
return 0;
}
All goes as expected and I get the following output.
The size of Items is 12
Which is all fine and good. However, I want to encapsulate the data within the class and only allow access through class functions.
The problem arises when I add the following code to "SetNumberOfElements" implementation.
void ProdContainer::SetNumberOfElements(int Elements)
{
Items.resize(Elements);
}
When I try to compile this "error C2228 left of '.resize' must have class/struct/union" appears and I am at a loss at what to do next.
I have searched high and low and cant seem to find any posts matching this particular problem, it's probably a schoolboy error. I've checked the MSDN site on error C2228 and as far as I can see Items is a substantiated variable of struct type ListOfItems, so I can't see why this error is appearing.
Is there a method for accessing a vector of a struct or some other aspect that I just can't see.
Please help, I am just about ready to explode.
You can only access static data from static functions. So change this
static void SetNumberOfElements(int Elements);
To this
void SetNumberOfElements(int Elements);
You cannot access non-static class members from the static function.
What you can do is to "switch" from static to non-static.
static void SetNumberOfElements( void * lParam, int Elements)
{
((ProdContainer*)lParam)->Items.resize( Elements );
}
Use it like this inside your class:
SetNumberOfELements( this, 10 );

c++ this parameter through System::Threading:ThreadStart to class member function

I'm writing in c++ a graphic user interfaced program and I need to create a threads in the program.
so I'm using System::Threading namespace to get my goal.
The function that I want to use as thread is a class member function, so here is what I've done:
Server::Server() // constructor
{
System::Threading::Thread^ T = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, this->RunServer)); // Server::RunServer
T->Start();
}
since it gave me those errors:
Error 2 error C3350: 'System::Threading::ThreadStart' : a delegate
constructor expects 2 argument(s)
Error 1 error C3867: 'Server::RunServer': function call missing
argument list; use '&Server::RunServer' to create a pointer to
member
I tried this call:
Server::Server() // constructor
{
System::Threading::Thread^ T = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(&Server::RunServer));
T->Start();
}
and received this errors:
Error 1 error C3364: 'System::Threading::ThreadStart' : invalid
argument for delegate constructor; delegate target needs to be a
pointer to a member
function
2 IntelliSense: invalid delegate initializer -- function is not a
member of a managed
class
as far as I know the second try did not succeed because Server::RunServer doesn't have address, so it's like to do &1.
by the way I tried to use the ThreadStart to create thread of none class memeber function and it worked fine.
I'm using win7 - visual studio 2012. How to make it work?
EDIT:
Server declaration:
class Server
{
public:
/* Fields */
std::string Port;
std::string Host;
WSADATA wsaData;
int ListenResult;
SOCKET ListenSocket;
SOCKET* ClientSocket;
SOCKADDR_IN* ADDR;
int ADDRSize;
struct addrinfo *result;
struct addrinfo hints;
std::vector<Client> Clients;
/* Methods */
Server();
std::wstring StringW(char* String);
void Print(std::wstring String);
std::wstring CurrentTime();
void ParseServerIni();
void RunServer();
void PartToString(Part* _Part);
void InsertListItem(std::string String);
void ClientHandler(SOCKET* _Sock, SOCKADDR_IN* _ADDR);
int ParsePacket(Packet &_Packet, int _Bytes, Byte** _PacketBlock);
};
You almost got the syntax right.
Assuming the declaration is:
public ref class Server
{
void RunServer();
};
Then you should combine your two approaches, by specifying both the object to invoke the method on, and the address of the method, with the name of the declaring class.
gcnew System::Threading::ThreadStart(this, &Server::RunServer)

a strange error

i define method in my class and this error occurred.
error C2371: redefinition; different basic types
my Method:
Buffer::SetSourceCode(string str)
{
SourceCode=str;
}
and my class:
class Buffer
{
string SourceCode;
int Index;
int PreIndex;
int Length;
public:
void SetSourceCode(string str);
void SetSourceFromFile();
string CopyString();
string Copy();
void SetPreIndex(void);
void IncreaseIndex();
void ReturnBack();
bool IsEnd();
char ReadChar();
Buffer(void);
~Buffer(void);
};
what is error ?
thanks.
Try to include headers:
#include <string>
using namespace std;
As far a i know, Buffer is a "reserved" (existing) name for a class in Visual-C++. Your class tries to redefine an existing type.
See
http://msdn.microsoft.com/en-us/library/system.buffer.aspx

How to initialize audio with Vala/SDL

I've been trying to figure this out for a few hours now.
In order to start up the audio, I need to create an SDL.AudioSpec object and pass it to SDL.Audio.Open. The problem is, AudioSpec is a class with a private constructor, so when I try to create one I get:
sdl.vala:18.25-18.43: error: `SDL.AudioSpec' does not have a default constructor
AudioSpec audiospec = new SDL.AudioSpec();
^^^^^^^^^^^^^^^^^^^
And if I try to just assign values to it's member vars like a struct (it's a struct in normal sdl) I get:
sdl.vala:20.3-20.25: error: use of possibly unassigned local variable `audiospec'
audiospec.freq = 22050;
^^^^^^^^^^^^^^^^^^^^^^^
I found the valac doc here: http://valadoc.org/sdl/SDL.AudioSpec.html
But it isn't much help at all.
The offending code block looks like this:
// setup the audio configuration
AudioSpec audiospec;
AudioSpec specback;
audiospec.freq = 22050;
audiospec.format = SDL.AudioFormat.S16LSB;
audiospec.channels = 2;
audiospec.samples = 512;
// try to initialize sound with these values
if (SDL.Audio.open(audiospec, specback) < 0)
{
stdout.printf("ERROR! Check audio settings!\n");
return 1;
}
Any help would be greatly appreciated!
Another update, as I'm still having some trouble. I've changed the vapi file, and this is what I have now:
public delegate void AudioCallback (out void* userdata, out uchar stream, int len);
[CCode (cname="SDL_AudioSpec")]
[Compact]
public struct AudioSpec {
public int freq;
public AudioFormat format;
public uchar channels;
public uchar silence;
public uint16 samples;
public uint16 padding;
public uint32 size;
public AudioCallback callback;
public void* userdata;
}// AudioSpec
I have a method that (tries?) to meet this function signature:
public void callback(out void* userdata, out uchar stream, int len)
{
stream = 0;
userdata = null;
}
And assigning it as:
audiospec.callback = gen.callback;
Needless to say, this still isn't working, get lots of errors:
/home/gukid/vala/soundgen.vala.c: In function ‘sound_gen_main’:
/home/gukid/vala/soundgen.vala.c:766:12: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’
/home/gukid/vala/soundgen.vala.c:766:72: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’
/home/gukid/vala/soundgen.vala.c:766:114: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’
/home/gukid/vala/soundgen.vala.c:768:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’
/home/gukid/vala/soundgen.vala.c:769:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’
/home/gukid/vala/soundgen.vala.c:770:21: warning: assignment from incompatible pointer type [enabled by default]
/home/gukid/vala/soundgen.vala.c:771:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’
/home/gukid/vala/soundgen.vala.c:772:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’
error: cc exited with status 256
So I'm at a bit of another sticky point.
3rd post: EUREKA! I have a solution! (debatable :P)
First off, the sdl.vapi looks like:
[CCode (cheader_filename = "SDL.h")]
public delegate void AudioCallback (void* userdata, uchar* stream, int len);
[CCode (cname="SDL_AudioSpec", has_type_id=false)]
public struct AudioSpec {
public int freq;
public AudioFormat format;
public uchar channels;
public uchar silence;
public uint16 samples;
public uint16 padding;
public uint32 size;
[CCode (delegate_target = false, type = "void*")]
public weak AudioCallback callback;
public void* userdata;
}// AudioSpec
And then I can just create a function:
public static void callback(void* userdata, uchar* stream, int len)
And:
audiospec.callback = callback;
Ahhh, finally my beautiful white noise generator is complete!
I think it's a bug in the VAPI. In sdl.vapi, try changing
[Compact]
public class AudioSpec {
to
public struct AudioSpec {
and
[CCode (cname="SDL_OpenAudio")]
public static int open(AudioSpec desired, AudioSpec obtained);
to
[CCode (cname="SDL_OpenAudio")]
public static int open(AudioSpec desired, out AudioSpec obtained);
and make your code look like:
AudioSpec audiospec = AudioSpec();
AudioSpec specback;
audiospec.freq = 22050;
audiospec.format = SDL.AudioFormat.S16LSB;
audiospec.channels = 2;
audiospec.samples = 512;
// try to initialize sound with these values
if (SDL.Audio.open(audiospec, out specback) < 0)
{
stdout.printf("ERROR! Check audio settings!\n");
return 1;
}
and give it a test. It seems to generate the correct code according to the SDL docs. If it works, consider submitting the VAPI changes to the Vala bugzilla.
Okay, the delegate:
public delegate void AudioCallback (out void* userdata, out uchar stream, int len);
has the C type:
void(*AudioCallback)(void**userdata, unsigned char* stream, int len);
where userdata and stream are write-only, which is not really what you want.
void (*callback)(void *userdata, Uint8 *stream, int len);
In this, userdata is just a pointer to some stuff for your use. In Vala's terms, it's the target of a delegate. stream is an array, but SDL has allocated it, so it's not out and len is the length of the array, so we can have Vala deal with that automatically with just uint8[] stream. Putting it all together:
[CCode(instance_pos = 0)]
public delegate void AudioCallback(uint8[] stream);
The instance_pos tells Vala where the userdata is. It normally assumes it to be last. As for the struct:
[CCode (cname="SDL_AudioSpec", destroy_function = "")]
public struct AudioSpec {
...
[CCode(delegate_target_cname = "userdata")]
public AudioCallback callback;
}
This will create a callback that stores the target in userdata. Now, to avoid leaking memory, Vala is going to try to assign a destructor to callback_target_destroy_notify...and now we're stuck because we have no member for that. So, let's back up and try again:
[CCode(has_target = false)]
public delegate void AudioCallback(void* userdata, uint8[] stream);
The has_target tells Vala there is no userdata and we include it manually. As for the struct:
[CCode (cname="SDL_AudioSpec", destroy_function = "")]
public struct AudioSpec {
...
public AudioCallback callback;
public void* userdata;
}
So, userdata will get passed to your callback, but you'll have to cast it yourself and you'll have to manage the memory. Additionally, when the structs go out of scope, Vala is going to call a destroy function. By specifying an empty string, it will do nothing. Normally, this frees memory inside the struct, but we don't need to worry here.

Resources