This is the header of a class I am working on in Visual C++ Express 2010:
/* custom class header to communicate with LynxMotion robot arm */
#include <vector>
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;
vector<int> currentPosition;
};
Everything worked fine until I changed the last line int currentPosition to vector<int> currentPosition. If I try to compile / debug now, I get these error messages:
error C2143: syntax error : missing ';' before '<'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2238: unexpected token(s) preceding ';'
I checked MSDN for some more info on these error codes, but I cannot figure out what is wrong with the code. Any ideas?
vector is template defined within std namespace, thus you should write std::vector<int> instead of vector<int>.
Alternatively you could write using namespace std; at the beginning of this file, but note that this is considered bad practice since it could cause some of names of your classes to become ambiguous.
You are using vector. Vector is contained with the namespace std. Namespaces encapsulate the normal scope of a variable/class. You cannot access elements within a namespace without resolving the scope somehow. There are 3 main ways to go about this:
#include <vector>
using namespace std;
You don't generally want to use this one, it will create issues because it allows you to see ANY function/class contained in the namespace std. This is bound to cause naming collisions.
Next way is:
#include <vector>
using std::vector;
This way is a little better. It makes vector visible to anything in the file or any file that includes said file. It is perhaps completely harmless in a .cpp file, because you shouldn't be including .cpp files anyways. And you should know what symbols you're or not. In the scenario of a .h/.hpp file, you may still not want to use this. Any file that has your .hpp file included their source code will see class vector as the name definition. This could be bad for users of your code, because they may not be expecting that symbol to be defined. In the case of an hpp file, you should always use the following:
#include <vector>
class myClass{
private:
std::vector myVector;
};
Using namespaces this way guarantees that it will only be visible exactly where the symbol is used, and nowhere else. This is the only way I'd use it in a .hpp file.
Related
The scenario is new and I believe it might be a bug in cpp-winrt module or the vc compiler.
The Problem
1. Create a "windows runtime component" using the cpp-winrt template for universal windows.
2. Note the namespace name defined in the idl file. By default the idl file is named as class.idl.
3. Add a "new standard cpp class" to the project using the class wizard.
4. Put the new class under the same namespace name as defined in the idl file.
5. Build the project.
a. The build should succeed.
6. Use the standard cpp class in the runtime implementation class.
7. Now try to build the project again.
a. The build will fail this time.
The Reason
1. cppwinrt.exe generates source files from the idl file.
2. The runtime implementation class namespace is prefixed by "winrt".
3. The standard cpp class is not prefixed by the namespace "winrt".
4. The vc compiler expects the standard cpp class namespace to start from "winrt"
5. Otherwise the name resolution fails even if you try to use the fully qualified namespace name.
Example runtime idl file
namespace NMLevel1.NMLevel2
{
[default_interface]
runtimeclass Class
{
Class();
void RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
Int32 MyProperty;
}
}
Example standard cpp file
#pragma once
#include <string>
using namespace std;
namespace NMLevel1::NMLevel2
{
class StdCPPClass
{
public:
StdCPPClass();
virtual ~StdCPPClass();
void method1();
int method2(int arg1);
wstring method3(wstring arg1);
};
}
Example runtime class implementation
#include "pch.h"
#include "Class.h"
#include "NMLevel1.NMLevel2.Class.g.cpp"
#include "StdCPPClass.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace winrt::NMLevel1::NMLevel2::implementation
{
void Class::RuntimeMethod1()
{
NMLevel1::NMLevel2::StdCPPClass stdcls;
Uri uri(L"http://aka.ms/cppwinrt");
//printf("Hello, %ls!\n", uri.AbsoluteUri().c_str());
printf("RuntimeMethod1(): Hello, %ls!\n", stdcls.method3(uri.AbsoluteUri().c_str()).c_str());
}
}
NMLevel1::NMLevel2::StdCPPClass stdcls; is not allowed without prefixing the namespace with winrt.
Is this a bug or a design limitation that cannot be overcome?
or How can I use the same namespace 'NMLevel1::NMLevel2' in idl and cpp files?
Name lookup in C++ is fairly involved, especially when namespaces get essentially merged through using declarations. To help the compiler identify the name you want, you'll have to be explicit, and use a fully qualified name (as opposed to a qualified name, as in the sample).
You'll have to change
void Class::RuntimeMethod1()
{
NMLevel1::NMLevel2::StdCPPClass stdcls;
// ...
}
to
void Class::RuntimeMethod1()
{
::NMLevel1::NMLevel2::StdCPPClass stdcls;
// ...
}
Note the leading :: scope resolution, which limits lookup to the global scope (or namespaces introduced into the global namespace through a using declaration). You'll find additional information here: Qualified name lookup.
I am new to c++ programming. I am trying few things
I tried using directive in following way as shown in below program just for trail it is throwing error
IDE used:VS 2015
language :VC++
Project type: library
Error occured is Error: Expected an identifier
This is in Stdafx.h
#define MANAGED_PUBLIC public ref
This is in trail.h
using namespace System;
namespace trail {
MANAGED_PUBLIC class Class1
{
// TODO: Add your methods for this class here.
};
}
I wanted to use MANAGED_PUBLIC instead of using public ref each and every time in whole project
You cannot do that. public ref is a context sensitive keyword. You cannot bury it down under a macro. C++/CLI compiler would process it differently than a regular compiler hence the macro outcome won't be public ref. You must type it everywhere.
You can use two macros:
#define MANAGED_PUB public
#define MANAGED_REF ref
MANAGED_PUB MANAGED_REF class Class1
{
// TODO: Add your methods for this class here.
};
You might try a compiler flag: -DMANAGED_PUBLIC="public ref" for your legacy code (quotes are stripped according to msdn).
Well, I have been struggling with this for days now. I am writing a custom game DLL for CryENGINE from scratch, and I cannot even get the solution compile with one simple class (Game.cpp) and a precompiled header (StdAfx.h).
Both Game.cpp and StdAfx.cpp will compile perfectly on their own, but compiling the solution throw tons of multiply defined errors. The class is simple because the definitions are just placeholders.
Game.h
#if !defined __GAME__H__
#define __GAME__H__
#pragma once
class CGame : public IGame
{
public:
CGame();
VIRTUAL ~CGame();
//IMPLEMENT: IGame Interface, all methods declared.
};
#endif
Game.cpp
#include "StdAfx.h" //PreComp header
#include "Game.h"
//Define all methods, each one has a simple definition.
StdAfx.h
#if !defined __STDAFX__H__
#define __STDAFX__H__
#pragma once
//Various CryENGINE includes
#endif
Output
error LNK2005: "struct SSystemGlobalEnvironment * gEnv" (? gEnv##3PEAUSSystemGlobalEnvironment##EA) already defined in StdAfx.obj
error LNK2005: "public: static long volatile _CryMemoryManagerPoolHelper::allocatedMemory" (?allocatedMemory#_CryMemoryManagerPoolHelper##2JC) already defined in StdAfx.obj
error LNK2005: "public: static long volatile _CryMemoryManagerPoolHelper::freedMemory" (?freedMemory#_CryMemoryManagerPoolHelper##2JC) already defined in StdAfx.obj
error LNK2005: "public: static long volatile _CryMemoryManagerPoolHelper::requestedMemory" (?requestedMemory#_CryMemoryManagerPoolHelper##2JC) already defined in StdAfx.obj
error LNK2005: "public: static int volatile _CryMemoryManagerPoolHelper::numAllocations" (?numAllocations#_CryMemoryManagerPoolHelper##2HC) already defined in StdAfx.obj
The list goes on...
What really throws me off is that each one will compile just fine individually, so syntax and references are good. What could possibly cause multiply defined errors when the solution is compiled as a whole?
I really appreciate help on this frustrating issue, thank you.
I'm not sure the errors are caused by the precompiled header, but here is the correct way to set up the precompiled header:
Right-click on the project name in Solution Explorer, select Properties, go to Configuration Properties | C/C++ | Precompiled Headers and set the Precompiled Header setting to Use (/Yu). Leave the other two settings below it to the default.
Right-click on StdAfx.cpp, go to the same setting and set it to Create (/Yc).
Well, I figured it out. There is a clever complex include that does not belong in the precompiled header:
#include <Platform_Impl.h>
This was causing all my problems, and by moving it to Game.cpp, everything is fine.
I have a unmanaged C++ dll for which I do not have access to code but have all methods declarations for.
Lets for simplicity say that .h looks like this:
#include <iostream>
#ifndef NUMERIC_LIBRARY
#define NUMERIC_LIBRARY
class Numeric
{
public:
Numeric();
int Add(int a, int b);
~Numeric();
};
#endif
and method implementation in .cpp file
int Numeric::Add(int a, int b)
{
return (a + b);
}
I simply want to call the add function from C++ in my C# code:
namespace UnmanagedTester
{
class Program
{
[DllImport(#"C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll", EntryPoint = "Add")]
public static extern int Add(int a, int b);
static void Main(string[] args)
{
int sum = Add(2, 3);
Console.WriteLine(sum);
}
}
}
After trying to execute I have the following error:
Unable to find an entry point named 'Add' in DLL 'C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll'.
I CAN NOT change C++ code. Have no idea what is going wrong.
Appreciate your help.
Using PInvoke you can only call global functions exported from Dll. To use exported C++ classes, you need to write C++/CLI wrapper. This is C++/CLI Class Library project, which exposes pure .NET interface, internally it is linked to unmanaged C++ Dll, instantiates a class from this Dll and calls its methods.
Edit: you can start from this: http://www.codeproject.com/KB/mcpp/quickcppcli.aspx#A8
If you need to create a wrapper, take a look at swig.org. It will generate one for most high level language like C#.
I just came across this program a few minutes ago while working the same problem that you are.
To use a class from native C++ from C# you need a C++/CLi wrapper in between, as mentioned by by previous answers. To actually do that, it is not very straight forward. Here is I link that tell you how to do it at a high level: C++/CLI wrapper for native C++ to use as reference in C#.
If you are quite new to this (like me), you might stumble on 1) -- the linking part. To solve that, you can see how I did here (see my question portion): Link error linking from managed to unmanaged C++ despite linking to .lib file with exported symbols
I have a bunch of warnings C4510 and C4610 when I use std::list with my class. It is a warning stating that default constructor is not available, and I want to disable them.
When I put:
#pragma warning(disable: 4510)
inside .cpp file that is instantiating this list nothing happens.
I tried placing this pragmas around function where I instantiate lists and even on top of the .cpp file but the results are the same - nothing happens. It only works if I disable warnings in properties dialog of .cpp file. I hate hiding stuff in properties like that because they get overlooked by developers. I would like to have them localized around the function. Is there something I could do about this?
EDIT:
Ok. This is how my code basically looks like. This code generates warnings 4510 and 4610 on warning level 4:
#include <list>
class foo {
public:
foo(int) { }
};
class bar {};
class problem_class {
foo m_foo;
const bar *m_bar;
public:
problem_class(const foo &_foo, const bar *_bar) : m_foo(_foo), m_bar(_bar) { }
};
void problem_fn(std::list<problem_class> &problem_collection) {
foo _foo(3);
problem_collection.clear();
problem_collection.push_back(problem_class(_foo, new bar));
}
int main(int , char **)
{
std::list<problem_class> collection;
problem_fn(collection);
return 0;
}
Instead of hiding the problem by disabling warnings, how about wrapping your class w/o a default constructor in a proxy class that does have a default constructor*. The proxy's default constructor can then do the proper initialization of the wrapped class. Then store the proxy class in the std::list. This would make your intent clear and eliminate the warning.
*assuming you can't for whatever reason actually make the wrapped class have an appropriatte default constructor.
Include #pragma before including <list>
#pragma warning (disable:4510)
#pragma warning (disable:4610)
#include <list>
You need to post some code that illustrates exactly what you are doing. Warning C4510 says:
The compiler cannot generate a default
constructor for the specified class
and no user-defined constructor was
created. You will not be able to
create objects of this type.
This doesn't seem to have anything to do with std::list, so it maybe that there is something wrong with your code.
I know this is not very helpful, but the code you posted looks fine to me and compiled with no warnings with g++ and comeau. I don't use VC++ anymore, so can't reall help further, I'm afraid.
Further Edit: Purely in the spirit of experimentation, what happens if you change:
const bar *m_bar;
to
bar *m_bar;
The MSDN docs for this warning say that:
There are several situations that
prevent the compiler from generating a
default constructor, including:
* A const data member.
Now the m_bar member isn't const (the thing it points to is) but I wonder if the compiler is a little confused about this.
#pragma warning (disable : 4510 4610)
#pragma warning (push, 3)
#include <list>
#pragma warning (pop)
#pragma warning (default : 4510 4610)
Ok, found it.
My project uses precompiled headers so in some header file that is included from StdAfx.h someone included list. When I added #pragma directives on top of the StdAfx.h everything worked. The thing that confused me is that when I added #pragma in .cpp file in front of
#include "StdAfx.h"
nothing worked (warnings were still displayed). Since list was included in precompiled headers, it had the same warning settings no matter what the .cpp file specified later on.
But, the strange thing is that even if I could not override settings in .cpp file, I could override them by specifying compile properties for that same file. How is that any different?