I am trying my first c++ project and am starting small, I think. I am using Eclipse Luna and am trying to take the defaults for build env everywhere that I can. I suspect that the following is vary naive code but you gotta start somewhere.
I will eventually have 4 co/sub projects in this:
Commandline interface to a static lib
".so" lib that will be dynamically loaded into a different, thied party app and uses the static lib
A static library, mentioned above, that does the back end work of the combined app.
A utility class (for now, maybe a small lib later) for utility classes and functions common to the other sub projects.
There are a ton of questions on best practices, namespaces, etc that I would like to ask but I'll keep this short.
I have the following c++ header file:
/*
* Utilities.h
*
*/
#ifndef UTILITIES_H_
#define UTILITIES_H_
// A
namespace UserTrackingUtilities {
// B
#include <string>
#include <exception>
using namespace std;
class MyException: public std::exception {
public:
MyException(std::string ss) : s(ss) {
}
~MyException() throw () {
} // Updated
std::string s;
const char* what() const throw () {
return s.c_str();
}
};
}
#endif /* UTILITIES_H_ */
This is an exception utility (found in a different StackOverflow thread) that I am wrapping in a namespace of my own -- I think.
Eclipse is showing several issues with this header file. I'll start with one: it doesn't like the std::string construct. It doesn't matter if I put the #includes and/or the using statements at point A or B.
I've also tried this with the Linux GCC and ADT tool chains.
Pointers and advice welcome.
#include <string>
#include <exception>
Should be before
namespace UserTrackingUtilities {
BTW:
If you use using namespace std, you can write string instead of std::string.
But I suggest not to use using namespace std to avoid name conflicts and ambiguities.
Update:
Here is a minimal working example:
#include <iostream>
#include <string>
#include <exception>
namespace UserTrackingUtilities {
class MyException: public std::exception {
public:
MyException(std::string ss) : s(ss) {
}
~MyException() throw () {
} // Updated
std::string s;
const char* what() const throw () {
return s.c_str();
}
};
}
int main()
{
UserTrackingUtilities::MyException ex("Hello World");
std::cout << ex.what() << std::endl;
return 0;
}
Related
iI would like to create a class Console in a namespace system. I defined the class like that:
Declaration
#pragma once
namespace system
{
class Console
{
public:
~Console();
void static writeLine();
private:
Console();
};
}
Definition
#include "Console.h"
#include <iostream>
system::Console::Console() {}
system::Console::~Console() {}
void system::Console::writeLine() {
std::cout << "test" << std::endl;
}
But the compiler is refusing to define this class because system is already defined in stdlib.h (included with iostream).
Do I have a solution to force the compiler to "ignore" the first definition of system ?
Thank you.
Stef
upper level namespace names should be reasonably unique (instead of being generic) and not clash not only with standard library but also with the rest of libraries out there. So just put namespace system into another namespace or rename it to something like
namespace stefv::system
{
Additionally you may want to use some sort of prefix specific for namespace names. For example ns_stefv::ns_system.
JSONParser.h
#ifndef UTILITY_CLASSES_JSONPARSER_H_
#define UTILITY_CLASSES_JSONPARSER_H_
#include <iostream>
#include <string>
#include <boost/property_tree/json_parser.hpp>
namespace Parsers {
class JSONParser {
boost::property_tree::ptree pTree;
public:
JSONParser();
virtual ~JSONParser();
void setJSON(char* JSON);
};
} /* namespace Parsers */
#endif /* UTILITY_CLASSES_JSONPARSER_H_ */
JSONParser.cpp
/*
* JSONParser.cpp
*
* Created on: 20-May-2016
* Author: arjun
*/
#include "JSONParser.h"
namespace Parsers {
JSONParser::JSONParser() {
// TODO Auto-generated constructor stub
}
JSONParser::~JSONParser() {
// TODO Auto-generated destructor stub
}
void JSONParser::setJSON(char* JSON){
std::string temp;
pTree.put("foo", "bar");
pTree.put("foor", "bawr");
std::ostringstream buf;
write_json (buf, pTree, false);
}
} /* namespace Parsers */
Defined above, are a cpp-header pair I've written for a JSONParser. However, an error is thrown when I try to use std::strings:
std::string is ambiguous.
It seems this happens whenever I include boost/property_tree/json_parser.hpp, i.e. whenever I delete the include for it, there is no error.
The same happens when I include something off of GeographicLib.
I'm on Ubuntu 16.04, my libraries are in usr/local/lib, and includes are in usr/local/include
The error is as follows:
Description Resource Path Location Type
'std::string' is ambiguous '
Candidates are:
' JSONParser.cpp /PSO-PathFinding/Utility Classes line 14 Semantic Error
Programming on Eclipse, using cdt.
Resolved. Not a C++ issue, or boost library issue. Seems to be a problem with the current eclipse workspace I'm working with.
I was attempting to follow the example of Finite State Filters in the Boost::iostreams documentation. However when I went to use the filter I got an error stating the ::imbue was not accessible because 'boost::iostreams::detail::finite_state_filter_impl' uses 'protected' to inherit from 'my_fsm'.
Frustrated I copied my code into the tests used to in the boost examples. The tests compile and pass. My conculsion is that I am probably mis-using the dual use filter defined by:
typedef io::finite_state_filter my_fsm_filter;
I feel that just pushing it onto a filtered_stream may not be proper, but I could not find a missing step. I am sure there must be a need to wrap the filter but I can find no example (though I am sure if I dug deep enough into the code used to test the boost code it has to be there somewhere).
here is a bit of example code:
#include <boost/mpl/vector.hpp>
#include <libs/iostreams/example/finite_state_filter.hpp>
namespace io = boost::iostreams;
struct my_fsm : io::finite_state_machine<my_fsm> {
BOOST_IOSTREAMS_FSM(my_fsm) // define skip and push.
typedef my_fsm self;
static const int beginline = 0;
static const int skipline = 1;
static const int dataline = 2;
typedef boost::mpl::vector <
row<beginline, is<'C'>, skipline, &self::skip>,
row<beginline, is_any, dataline, &self::push>,
row<skipline, is<'\n'>, beginline, &self::skip>,
row<skipline, is_any, skipline, &self::skip>,
row<dataline, is<'\n'>, beginline, &self::push>,
row<dataline, is_any, dataline, &self::push>
> transition_table;
};
typedef io::finite_state_filter<my_fsm> my_fsm_filter;
#include <iostream>
#include <string>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/stream.hpp>
namespace io = boost::iostreams;
int main() {
io::stream<io::file_sink> out(io::file_sink("outputfile.txt"));
io::filtering_istream in;
my_fsm_filter infsm;
in.push(my_fsm_filter());
in.push(io::file_source("inputdata.txt"));
while (in) {
std::string line;
if(std::getline(in, line)) {
//std::cout << line << std::endl;
out << line << std::endl;
}
}
return 0;
}
I personally feel that there is a bug in the sample header with respect to this imbue call.
However, you can work around it by changing the typedef to
struct my_fsm_filter : io::finite_state_filter<my_fsm> {
using io::finite_state_filter<my_fsm>::imbue;
};
This explicitly exposes the imbue method as public on the derived type. I haven't looked at the sample program that you reported to be working (because you didn't link to it). But it's possible they used a similar hack.
In my tests, a similar edit to finite_state_filte.hpp L278 to add
using base_type::imbue;
to class finite_state_filter has the same effect.
PLEASE SEE UPDATE BELOW
(RESOLVED) Also I have extended this into a second question here Implement a C# DLL COM File In Unmanaged C++ Program
I have researched this to the end of the internet without finding a real, understandable, human example of how to do this.
I have a C# DLL that encrypts and decrypts text.
I don't want to / don't have the intellectual capability to rewrite this in C++ un-managed code. So instead I created a C++/CLR class that interfaces with the C# dll.
NOW I need to know how to call the managed C++ from my unmanaged code.
Here is my managed code and it is verified that it works
// clrTest.cpp : main project file.
#include "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>
using namespace cSharpRiJHarn;
using namespace System;
String^ Encrypt(String ^s)
{
return RijndaelLink::encrypt(s);
}
String^ Decrypt(String ^s)
{
return RijndaelLink::decrpyt(s);
}
int main()
{
//Console::WriteLine(Encrypt("It Works"));
//Console::WriteLine(Decrypt(Encrypt("It Works")));
//Console::ReadLine();
return 0;
}
Now ONCE AGAIN I HAVE researched this.
I have seen allllllll the bad/overly complicated explanations
I know I need to use something called COM or Interop
I don't know how this works and I am just looking for a very simple explanation.
Thanks for the help.
UPDATE
I have turned the C# DLL into a COM File
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace cSharpRiJHarn
{
[Guid("GuiD CODE REMOVED")]
public interface DBCOM_Interface
{
[DispId(1)]
String encrypt(string s);
[DispId(2)]
String decrpyt(string s);
}
[Guid("GuiD CODE REMOVED"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface DBCOM_Events
{
}
[Guid("GuiD CODE REMOVED"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]
public class RijndaelLink : DBCOM_Interface
{
public String encrypt(String s)
{
return Rijndael.EncryptString(s);
}
public String decrpyt(String s)
{
return Rijndael.DecryptString(s);
}
}
}
Now I am just need to know how to implement this in unmanaged C++...
I have tried both adding just the files to the C++ project and also adding the entire cSharpRiJHarn Project to this solution. Neither work.
#import "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <iostream>
//using namespace cSharpRiJHarn;
int main(){
cSharpRiJHarn::RijndaelLink::encrypt("It works");
char ch;
std::cin>>ch;
return 0;
}
This is one of the errors I am getting.
Error 6 error C2653: 'cSharpRiJHarn' : is not a class or namespace
name
and
Error 8 IntelliSense: cannot open source file
"C:/.../.../Documents/Visual Studio
2010/Projects/unmannagedCPPExample/unmannagedCPPExample/Debug/cSharpRiJHarn.tlh" c:......\documents\visual
studio
2010\projects\unmannagedcppexample\unmannagedcppexample\unmannagedcppexample.cpp
You could use the cool C++ Marshaling library provided by Microsoft, something like this:
#include "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include "msclr\marshal_cppstd.h" // marshaling library
using namespace cSharpRiJHarn;
using namespace System;
using namespace msclr::interop; // marshaling library
std::wstring Encrypt(std::wstring s)
{
return marshal_as<std::wstring>(RijndaelLink::encrypt(marshal_as<String^>(s)));
}
std::wstring Decrypt(std::wstring s)
{
return marshal_as<std::wstring>(RijndaelLink::decrypt(marshal_as<String^>(s)));
}
First, your methods receive and return a String^ which is a managed object. Unmanaged code does not know this type, and cannot create such object. So, you will need to wrap the function call such that the function marshal the managed type to something that the unmanaged code can understand.
After that, you can add the DllExport attribute to the managed method, as discussed here.
I have two libraries included in my program which both have the same function name, but I need to be able to use both, but I also need C++ to know which one I'm referring to (in certain places I will only be referring to one or the other). The reason why I'm doing this is because I am making my own library and I want to have certain names for my functions, but they are conflicting with functions in someone else's library that I've included, and to make matters worse, some of my functions in my library actually USE the functions in the other persons library which has the same name.
My library is just a .h/.cpp file by the way. Also, when calling MY functions, I don't want any extra luggage such as myNameSpace::myFunc(). I just want to call it myFunc(). However, I don't mind calling the other persons function using a namespace (though I don't want to modify their library in case I break something). (I'm completely new to C++ btw)
HERES MY NEW (TEST - SO FAR) CODE : NOT WORKING W/ ERRORS:
error C2668: 'myFunc' : ambiguous call to overloaded function
main program.cpp
#include "otherslib.h"
#include "mylib.h"
#include <iostream>
using namespace myNamespace;
int main(){
std::cout << myFunc() << std::endl;
return 0;
}
mylib.h
#pragma once
namespace myNamespace{
int myFunc();
}
mylib.cpp
#include "mylib.h"
namespace myNamespace{
int myFunc(){
return 1;
}
}
otherslib.h
#pragma once
int myFunc();
otherslib.cpp
#include "otherslib.h"
int myFunc(){
return 0;
}
You should define your functions in a namespace, and use the namespace when calling them.
namespace myNamespace
{
int myFunc(etc) { ... }
}
int main() {
cout << myNamespace::myFunc();
}
To avoid having to specify your namespace all the time, you could do something like this:
namespace myNamespace
{
int myFunc(etc) { ... }
int main()
{
// Call your own myFunc:
myFunc();
// Call their myFunc:
::myFunc();
}
}