Where should I put my DECLSPEC for a namespace? - c++

given the following namespace, where do I put my declspec (for dll export) i I want all the methods in said namespace to be exported into the DLL?
namespace AguiText {
void drawTextArea(AguiGraphicsManager *g, const AguiFont &font,const AguiRectangle &area,
const AguiColor &color, const std::vector<std::string> &lines,
AguiHorizontalAlignmentEnum horizontalAlignment, AguiVerticalAlignmentEnum verticalAlignment);
void divideText(std::vector<std::string> &words,
const std::string &text,const AguiFont &font, int maxWidth = -1);
void makeTextLines(const AguiFont &font,const std::vector<std::string> &words,
std::vector<std::string> &lineWords, int maxWidth );
void pointInTextArea(const AguiFont &font,
const AguiRectangle &area, const AguiPoint &point,
const std::vector<std::string> &lines, AguiRectangle &retRect,
int &retIndex, AguiHorizontalAlignmentEnum horizontalAlignment, AguiVerticalAlignmentEnum verticalAlignment);
}
Thanks

There is no need to export a namespace. From a compiled code perspective, namespaces are meaningless. You cannot reference them in code, they just define scope.
Namespaces wind up becoming part of class/function names during the name mangling process. They are not separate entities once a source file is compiled.
If you want to export the contents of a namespace, you need to export those entities, not the namespace itself.

Related

c++: g++: extern "C" function definition?

I am having trouble creatiung a C++ library with a extern "C" function interface. I have the following header
#ifndef MYUTILITIES_H_
#define MYUTILITIES_H_
namespace MYUtilities {
static std::string UpperCase(std::string);
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();
}
};
} /* namespace ITGUtilities */
/*
* General utility functions
*/
extern "C" const char * UpperCase(const char *);
#endif /* MYUTILITIES_H_ */
source file
#include "ITGUtilities.h"
namespace ITGUtilities {
const char * UpperCase(const char * str) {
std::string tmp = str;
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
return tmp.c_str();
}
std::string UpperCase(std::string str) {
std::string tmp = str;
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
return tmp;
}
} // namespace ITGUtilities
In the .cpp source file I have tried defining the char *UpperCase(const char *) routine inside and outside of the namespace. In either case nothing that tries to use this library can find a reference for the extern function.
I have seen an example in the MySQL C++ cppcon/driver.h header where the extern definition is in the header but outside the namespace.
extern "C"
{
CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance();
/* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */
CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib);
}
I just don't know what magic I should be using here.
help?
Use the curly braces to define your external C function:
extern "C"
{
UpperCase(const char *);
}
First of all, do not define extern functions in namespaces, it makes no sense. To check what was the name of generated function in object file, use utility called nm (on *nix). It should tell you of the name was mangled or not.
In your case, I assume the problem is that you have an overload with a different name and C++ linkage. I suggest you name your C-linkage function differently.

declaration of static function outside of class is not definition

I am getting this error when I compile with GCC:
error: declaration of 'static int utils::StringUtils::SplitString(const std::string&, const std::string&, std::vector<std::basic_string<char> >&, bool)' outside of class is not definition
Code:
Header:
namespace utils
{
/*
* This class provides static String utilities based on STL library.
*/
class StringUtils
{
public:
/**
* Splits the string based on the given delimiter.
* Reference: http://www.codeproject.com/Articles/1114/STL-Split-String
*/
static int SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties = true );
};
};
Source:
namespace utils
{
int StringUtils::SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties );
{
....
}
}
Take the semi-colon off the end of the definition in your source file! Copy-paste error =)
I believe you need to lose that semicolon in your source file. Should be:
namespace utils
{
int StringUtils::SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties ) // <--- No more semi-colon!
{
....
}
}

C++ and Objective-c

i built a static library,and add the .h file to my project,
in all the class in the .h files,something like this :
class StartOp
{
static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParameters *params);
static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunParameters *params);
static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outFile);
static void detectBPM(WavInFile *inFile, RunParameters *params);
int start(const int nParams, const char * const paramStr[]);
};
i got this error:
StartOp.h:18: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'StartOp'
**EDIT**
i fix this problem by changing the file ex to mm.
now i want to use this code and i want to call from this class ,this code is an c++ class that i want to call him from an objective-c class:
#ifndef _STARTOP_H_
#define _STARTOP_H_
namespace soundtouch
{
class StartOp
{
static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParameters *params);
static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunParameters *params);
static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outFile);
static void detectBPM(WavInFile *inFile, RunParameters *params);
static int start(const int nParams, const char * const paramStr[]);
};
}
#endif
to the
static int start(const int nParams, const char * const paramStr[]);
method from my objective-c iphone app.
The code you posted is not C; it is rather C++.
Now, Objective-C and C++ can interoperate, but you need to use .mm extensions on the Objective-C side.
So if you are importing the .h. file into a .m file, you get obviously errors because the compiler is not expecting a class definition (C++). If you import the .h file into a .mm file, you have some chance that it will work (if all the rest is correct, I mean).
If you need more help, please provide more code, so that we can understand better what you are doing.

Define static method in source-file with declaration in header-file in C++

I am having a little trouble working with static methods in C++
Example .h:
class IC_Utility {
public:
IC_Utility();
~IC_Utility();
std::string CP_PStringToString( const unsigned char *outString );
void CP_StringToPString( std::string& inString, unsigned char *outString, short inMaxLength );
static void CP_StringToPString( std::string& inString, unsigned char *outString);
void CP_StringToPString( FxString& inString, FxUChar *outString);
};
Example .cpp:
static void IC_Utility::CP_StringToPString(std::string& inString, unsigned char *outString)
{
short length = inString.length();
if( outString != NULL )
{
if( length >= 1 )
CPLAT::CP_Utility::CP_CopyMemory( inString.c_str(), &outString[ 1 ], length );
outString[ 0 ] = length;
}
}
I wanted to make a call like:
IC_Utility::CP_StringToPString(directoryNameString, directoryName );
But I get an error:
error: cannot declare member function 'static void IC_Utility::CP_StringToPString(std::string&, unsigned char*)' to have static linkage
I dont understand why I cannot do this. Can anyone help me understand why and how to achieve what I want?
Remove static keyword in method definition. Keep it just in your class definition.
static keyword placed in .cpp file means that a certain function has a static linkage, ie. it is accessible only from other functions in the same file.
Keywords static and virtual should not be repeated in the definition. They should only be used in the class declaration.
You don't need to have static in function definition
Probably the best course of action is "do it as std lib does it". That is: All inline, all in headers.
// in the header
namespase my_namespace {
class my_standard_named_class final {
public:
static void standard_declared_defined_method () {
// even the comment is standard
}
} ;
} // namespase my_namespace
As simple as that ...
Static member functions must refer to static variables of that class. So in your case,
static void CP_StringToPString( std::string& inString, unsigned char *outString);
Since your member function CP_StringToPstring is static, the parameters in that function, inString and outString should be declared as static too.
The static member functions does not refer to the object that it is working on but the variables your declared refers to its current object so it return error.
You could either remove the static from the member function or add static while declaring the parameters you used for the member function as static too.

Undefined reference

I'm getting this linker error. I know a way around it, but it's bugging me because another part of the project's linking fine and it's designed almost identically.
First, I have namespace LCD. Then I have two separate files, LCDText.h and LCDGraphic.h.
LCDText.h:
//[snip]
void TextDraw(Widget *w);
void TextBarDraw(Widget *w);
void TextHistogramDraw(Widget *w);
void TextIconDraw(Widget *w);
void TextBignumsDraw(Widget *w);
void TextGifDraw(Widget *w);
}; // End namespace
LCDGraphic.h:
//[snip]
void GraphicDraw(Widget *w);
void GraphicIconDraw(Widget *w);
void GraphicBarDraw(Widget *w);
void GraphicHistogramDraw(Widget *w);
void GraphicBignumsDraw(Widget *w);
void GraphicGifDraw(Widget *w);
}; // End namespace
And in WidgetBignums.h I have:
//[snip]
using namespace LCD;
extern void TextBignumsDraw(Widget *w);
extern void GraphicBignumsDraw(Widget *w);
template <class T>
WidgetBignums<T>::WidgetBignums(Generic<T> *v, std::string n, Json::Value *section,
int row, int col) : Widget(n, section, row, col,
WIDGET_TYPE_BIGNUMS | WIDGET_TYPE_RC | WIDGET_TYPE_SPECIAL) {
if( v->GetType() == LCD_TEXT )
Draw = TextBignumsDraw; // Line 66
else if( v->GetType() == LCD_GRAPHIC )
Draw = GraphicBignumsDraw;
else
Draw = NULL;
//[snip]
And I get the following linker error:
LCDControl.o: In function `WidgetBignums':
/home/starlon/Projects/LCDControl/WidgetBignums.h:66: undefined reference to `LCD::TextBignumsDraw(LCD::Widget*)'
Now here's one way to fix it, but I don't like it. I can move LCD::TextBignumsDraw outside of the LCD namespace and it works. Strange enough, the linker sees LCD::GraphicBignumsDraw. Any clues?
Edit: I'm using gcc 4.4.1-2 on Fedora 11. Using SCons to compile.
Edit: Here's WidgetBignums, showing Draw.
template <class T>
class WidgetBignums : public Widget {
Generic<T> *visitor_;
std::vector<char> FB_;
std::vector<char> ch_;
int min_;
int max_;
int update_;
int layer_;
Property *expression_;
Property *expr_min_;
Property *expr_max_;
QTimer *timer_;
void (*Draw)(Widget *);
public:
WidgetBignums(Generic<T> *visitor, std::string name, Json::Value *section, int row, int col);
~WidgetBignums();
void TextScroll() {};
void SetupChars();
void Update();
void Start();
void Stop();
std::vector<char> GetFB() { return FB_; }
std::vector<char> GetCh() { return ch_; }
Generic<T> *GetVisitor() { return visitor_; }
};
Edit: Here's TextBignumsDraw's signature.
//[snip]
void TextBignumsDraw(Widget *w) {
//[snip]
Edit: Incidentally, I'm getting the same error for TextHistogramDraw and TextGifDraw as well. TextIconDraw and the others are fine.
Where is the definition for LCD::TextBignumsDraw()? That's what the linker seems to be complaining about. Not the declaration, but the actual definition of the function.
The fact that when you move the declaration out of namespace LCD things start working indicates that the definition for TextBignumsDraw() is in the global namespace, not the LCD namespace.
This (in some .cpp file):
void TextBignumsDraw(Widget *w) {
// ...
}
Needs to be wrapped in a
namespace LCD {
}
block.
Try dropping the "using namespace LCD", and change that line 66 to:
Draw = LCD::TextBignumsDraw;
That's more explicit, which may help the linker understand what you're asking for.
Besides, you should never say "using namespace Anything" in a header file. It hoists everything in that namespace out into the global space for every user of that header. That almost completely destroys the value of having a namespace in the first place. You should hoist things out like this in the narrowest scope that's practical. Sometimes I put "using namespace foo" at the top of a single function, for instance, if that's the only user of the bits in the namespace within a given .cpp file.