DLL syntax error - c++

I'm trying to create a dll with multiple functions, in Visual C++ 2010, and I keep getting a syntax error that is related to using strings, or so it seems.
1>c:\users\new\documents\visual studio 2010\projects\getint\getint\getint.h(9): error C2061: syntax error : identifier 'string'
The code can be seen below. I literally followed what I did last time; although the last dll I made had 1 function and no boolean or string values.
#include <string>
class getInt
{
public:
//NB :: static __declspec(dllexport) is need to export data from the dll!
//This declares the function for retrieving an integer value from the user
static __declspec(dllexport) int toInt (const string &inStr);
static __declspec(dllexport) int getNum();
static __declspec(dllexport) bool isValidInt (const string& str);
};
There are several other syntax errors but I believe they are arising due to the string being before the other functions.

There is no string class in the global scope, just the one in the std namespace. So, change the functions to accept std::strings instead.
#include <string>
class getInt
{
public:
//NB :: static __declspec(dllexport) is need to export data from the dll!
//This declares the function for retrieving an integer value from the user
static __declspec(dllexport) int toInt (const std::string &inStr);
static __declspec(dllexport) int getNum();
static __declspec(dllexport) bool isValidInt (const std::string& str);
};

string is in the std namespace, so prefix with std::
#include <string>
class getInt
{
public:
//NB :: static __declspec(dllexport) is need to export data from the dll!
//This declares the function for retrieving an integer value from the user
static __declspec(dllexport) int toInt (const std::string &inStr);
static __declspec(dllexport) int getNum();
static __declspec(dllexport) bool isValidInt (const std::string& str);
};

Related

__declspec(dllexport) and __declspec(dllimport) in C++

I often see __declspec(dllexport) / __declspec(dllimport) instructions on Windows, and __attribute__((visibility("default"))) on Linux with functions, but I don't know why. Could you explain to me, why do I need to use theses instructions for shared libraries?
The Windows-exclusive __declspec(dllexport) is used when you need to call a function from a Dll (by exporting it) , that can be accessed from an application.
Example This is a dll called "fun.dll" :
// Dll.h :
#include <windows.h>
extern "C" {
__declspec(dllexport) int fun(int a); // Function "fun" is the function that will be exported
}
// Dll.cpp :
#include "Dll.h"
int fun(int a){
return a + 1;
}
You can now access the "fun" from "fun.dll" from any application :
#include <windows.h>
typedef int (fun)(int a); // Defining function pointer type
int call_fun(int a){
int result = 0;
HMODULE fundll = LoadLibrary("fun.dll"); // Calling into the dll
if(fundll){
fun* call_fun = (fun*) GetProcAddress(fundll, "fun"); // Getting exported function
if(call_fun){
result = call_fun(a); // Calling the exported fun with function pointer
}
}
return result;
}

Static variables and initialization

I am trying to reach a static variable declared in MyClass.h from MyClass.cpp. But I get following errors.
I made a research but still have no clue why my code does not compile. I use visual studio 2013.
MyClass.h
#ifndef __MyClass_h_
#define __MyClass_h_
class MyClass {
static int x;
public:
static int y;
};
#endif
MyClass.cpp
#include "MyClass.h"
void MyClass::sor() (const string& var1, const unsigned count) const {
// What goes here? See below for what I have tried
}
So, if I use:
int MyClass::x=8;
This says int MyClass::x redefinition and MyClass::x 'MyClass::x' : definition or redeclaration illegal in current scope
If I use:
MyClass::x=8;
This gives the error 1 unresolved external.
If I use:
MyClass::y=8;
This also gives the error 1 unresolved external.
If I use:
int MyClass::y=8;
This says int MyClass::y redefinition and 'MyClass::y' : definition or redeclaration illegal in current scope
You need to understand you don't have a static variable in a header, how other answers suggest. You have a static member of a class, which is perfectly fine.
In order to access it you write: MyClass::x. You need to initialize it also.
Unrelated to the static member, you need to declare the method also:
header:
#ifndef __MyClass_h_
#define __MyClass_h_
class MyClass {
static int x;
public:
static int y;
void sor() (const string& var1, const unsigned count) const;
};
#endif
source file:
#include "MyClass.h"
int MyClass::x = 0; // intialization
void MyClass::sor() (const string& var1, const unsigned count) const {
MyClaxx::x = 11; // access it
}
You have a declaration for the static variable but don't have the definition for it. In order to use static class members you should define them in the corresponding translation unit. You can't do it in the header file because it will violate ODR(one definition rule) so you should define it in the .cpp file to confrom the aforementioned rule.
So you have to put int MyClass::x = 0; in your cpp file in global scope(or under the namespace if you have one) to get it working. Note, that you could use whatever value insted of 0 or even didn't provide any(in this case it will be 0 anyway, due to special treatment of global(static) variables.)
When static variable is declared in a header file is its scope limited to .h file or across all units.
Refer here for source
This is simple. When you declare a static variable in a header file, it's scope is limited to header file. When you going to use that static variable in a .cpp file you getting an error like this. It is because you didn't give the definition of the static variable. So in any of the .cpp file you need to give the definition of static variable. ex :
.h file
class MyClass {
static int x;
.....
}
Top of the .cpp file you should define the static variable like this.
#include "MyClass.h"
int MyClass::x = 0 ;
void MyClass::sor() (const string& var1, const unsigned count) const {
MyClass::x = 8 ; // you can access without any issue
}

Unmangling of functions not working in Visual C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Name mangling of c++ classes and its member functions?
I created a Visual C++ dll. It is working and i can call my Thrust methods from cuda through this dll in c#.
The only problem is, that i am not able to unmangle the function names. I would like to have the normal names so i would not need to use an Entrypoint with the convention.
Here is my code.
This is my header
//ThrustCH.h
#pragma once
enter code here__declspec(dllexport) class ThrustFuncs
{
__declspec(dllexport) static int maxValueThrust(int *data, int N);
__declspec(dllexport) static double maxValueThrust(double *data, int N);
__declspec(dllexport) static int* sort(int* data, int N);
__declspec(dllexport) static double* sort(double* data, int N);
__declspec(dllexport) static int simple(int N);
};
This is my cpp
// thrustDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "thrustH.h"
#include "thrustCH.h"
extern "C" {
__declspec(dllexport) int ThrustFuncs::maxValueThrust(int *data, int N){
return thrustH::maxValue(data,N);
}
__declspec(dllexport) double ThrustFuncs::maxValueThrust(double *data, int N){
return thrustH::maxValue(data,N);
}
__declspec(dllexport) int* ThrustFuncs::sort(int* data, int N){
return thrustH::sort(data,N);
}
__declspec(dllexport) double* ThrustFuncs::sort(double* data, int N){
return thrustH::sort(data,N);
}
__declspec(dllexport) int ThrustFuncs::simple(int N){
return N;
}
}
I tried to use extern "C" and __declspec(dllexport) almost everywhere put i guess I'm doing something wrong. Could you help me please?
It seems you are trying to export C++ functions but want them to have a C name.
There is no direct way to do that, mainly because it doesn't make sense.
C doesn't have classes (or namespaces for that matter) and those usually are involved in the C++ name mangling. That is, don't write the functions you intend to export with a C name decoration in a class declaration.
You can, however, still write C functions (in an extern "C" block) in which you call your C++ functions, methods, or classes.
Something like:
class foo
{
static int bar(const std::string& str) { return static_cast<int>(str.size()); }
}
extern "C"
{
int bar(const char* str)
{
// Call C++ version of the function.
try
{
return foo::bar(str);
}
catch (std::exception&)
{
// Handle it somehow
}
}
}
You may want to use __cdecl for the functions that you want to export which will not mangle the names.
Refer: /Gd, /Gr, /Gz (Calling Convention)

What is the right way to return a reference to a class static data member? (I'm using Qt, in case it makes a difference)

I'm trying to get the address of a class static data member from a DLL and keep it around in host code. However, I'm loosing the pointer / reference to the member the minute I exit the method in the dll-manager which opens all the (Windows typedef) HINSTANCE s, even though I'm keeping them open.
My setup is:
A Qt GUI application, which includes a class that loads plugins from dlls. This dll-manager class doesn't use Qt stuff but for Qdir and Qstrings here and there...
The dll-manager should issue a bunch of LoadLibrary() calls to open DLLs and for each, call an exported function which returns the address of a static "info" struct inside the class the DLL exports.
For instance, The DLL class looks like this:
BlackNWhite.h
#ifdef BLACKNWHITE_EXPORTS
#define BLACKNWHITE_API __declspec(dllexport)
#else
#define BLACKNWHITE_API __declspec(dllimport)
#endif
// This class is exported from the BlackNWhite.dll
class BLACKNWHITE_API CBlackNWhite : PCOperatorBase
{
public:
CBlackNWhite(void);
virtual ~CBlackNWhite(void);
virtual int process(int* inBuffer, int* outBuffer, int bufferSize);
void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters);
static const OperatorInfo& info();
protected:
static OperatorInfo operatorInfo;
};
extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance();
extern "C" __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo();
BlackNWhite.cpp
#include "stdafx.h"
#include "BlackNWhite.h"
PCOperatorBase::OperatorInfo CBlackNWhite::operatorInfo = {L"Black N White", L"modifier", L"color"};
const PCOperatorBase::OperatorInfo& CBlackNWhite::info()
{
return CBlackNWhite::operatorInfo;
}
extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance()
{
return (PCOperatorBase*)(new CBlackNWhite());
}
extern "C" __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo()
{
return CBlackNWhite::info();
}
CBlackNWhite::CBlackNWhite()
: PCOperatorBase()
{
ParameterDescriptor newParameter;
newParameter.label = L"Parameter 1";
parameters.push_back(newParameter);
}
CBlackNWhite::~CBlackNWhite()
{
}
int CBlackNWhite::process(int* inBuffer, int* outBuffer, int bufferSize)
{
while(bufferSize--)
*outBuffer++ = *inBuffer++;
return 0;
}
void CBlackNWhite::getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters)
{
outParameters = &parameters;
}
And this class inherits from a base class:
PCOperatorBase.h
#pragma once
#include "PCOperatorParameters.h"
#include <vector>
class PCOperatorBase
{
public:
typedef struct OperatorInfo
{
wchar_t* name;
wchar_t* type;
wchar_t* subtype;
} OperatorInfo;
PCOperatorBase(void){};
virtual ~PCOperatorBase(void){};
virtual void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters) = 0;
virtual int process(int* inBuffer, int* outBuffer, int bufferSize) = 0;
protected:
std::vector<ParameterDescriptor>parameters;
};
And the DLL-manager has two relevant methods. One builds the list of available plugins and the other one just returns the string names of the plugins.
void PCOperatorManager::buildOperatorList(const QString path)
{
QDir operatorDirectory(QDir::currentPath() + path);
if(operatorList.size())
operatorList.clear();
QStringList operatorNameList = operatorDirectory.entryList(QStringList("*.dll"));
typedef PCOperatorBase::OperatorInfo*(*PCOClassInfoFunction)();
for(QStringList::iterator PCOClassName = operatorNameList.begin();
PCOClassName != operatorNameList.end();
PCOClassName++)
{
HINSTANCE PCOClassHandle;
if((PCOClassHandle = LoadLibrary((operatorDirectory.absolutePath() + "/"+ *PCOClassName).toStdWString().c_str())))
{
OperatorDescriptor newPCOClassDescriptor;
newPCOClassDescriptor.handle = PCOClassHandle;
newPCOClassDescriptor.info = (*((PCOClassInfoFunction)GetProcAddress(PCOClassHandle, "getOperatorInfo")))();
operatorList.push_back(newPCOClassDescriptor);
printf("\n we have: %ls", operatorList[0].info->name);
}
}
}
QStringList PCOperatorManager::getOperatorNameList()
{
QStringList operatorNameList;
printf("\n the list length is: %i", operatorList.size());
for(int i = 0; i < operatorList.size(); i++)
printf("\n we have again: %ls", operatorList[0].info->name);
//operatorNameList << QString::fromWCharArray((*PCOClass).info.name);
return operatorNameList;
}
What's happening is: inside buildOperatorList() I can access the static member of the DLL-class and assign it to the info member in the OperatorDescriptor struct. That is, the "test" printf statement that reads "we have" does print out the right value for that field.
However, inside getOperatorNameList() the info member is not valid anymore.
My line of thought is that what I'm doing is:
I have a pointer to a OperatorInfo struct, called info.
I get the address of a static OperatorInfo struct in the DLL-class,
called operatorInfo.
I assign the address of the class' operatorInfo to the pointer
called info. That is info = &CBlackNWhite::operatorInfo;
At this point, the pointer should stay valid as long as I don't issue a FreeLibrary() on the DLL HINSTANCE
So what's going on?
I see here operatorList is not a member variable of PCOperatorManager once it is added and constructed as in buildOperatorList I think you should ave access in getOperatorNameList()

Error while trying to compile a DLL with a static class function in VC++

I am trying to take some functions that I've made and tested with in a standalone application. Now that I am trying to make a DLL I am getting a few errors stating that the function has been redefined and that the return parameters don't match. This seems to be the only time I am getting these errors, I've tested it by removing this class and it compiles fine as well as the stand-alone app with a main.cpp referencing these directly. Below are the errors and the h and cpp files:
Error 7 error C2371: 'Parser::parse' : redefinition; different basic
types c:\users\seb\documents\visual studio
2005\projects\TestDLL\TestDLL\parser.cpp 17
Error 4 error C2526: 'Parser::parse' : C linkage function cannot
return C++ class 'std::vector<_Ty>' c:\users\seb\documents\visual
studio 2005\projects\TestDLL\TestDLL\parser.h 28
Error 6 error C2556: 'IDVec Parser::parse(const char *)' : overloaded
function differs only by return type from 'void Parser::parse(const
char *)' c:\users\seb\documents\visual studio
2005\projects\TestDLL\TestDLL\parser.cpp 17
Also find the .h file and the function from the .cpp as well:
Parser.h
#ifndef PARSER_H
#define PARSER_H
#if defined DLL_EXPORT
#define TESTAPI __declspec(dllexport)
#else
#define TESTAPI __declspec(dllimport)
#endif
#include <iostream>
#include <vector>
typedef struct _ListEntry {
std::string id, path;
} ListEntry;
typedef std::vector<ListEntry> IDVec;
extern "C"
{
class TESTAPI Parser
{
public:
Parser(void);
~Parser(void);
static IDVec parse(const char* Buffer);
private:
static size_t nextLine(std::string& rstrText, size_t pos);
static std::string nextWord(std::string& rstrText, size_t pos);
static void fixOSSpecificPath(std::string& rstrPath);
};
}
#endif
Parser.cpp
IDVec Parser::parse(const char* Buffer)
{
std::string s = Buffer;
IDVec v;
// Doing stuff here
return v;
}
Thanks for any advice
Remove extern "C" around your class definition.