lpvoid to interface reference invalid cast exception - casting

I have problems casting a class to LPVOID and than recasting it to interface class. Here is the simplified code:
public interface class IEventRaiser
{
void fireAppDisconnect()
// some other methods
}
interface class ISpecificEventRaiser : IEventRaiser
{
// some specific methods
}
public ref class ManagedItem
{
ManagedItem()
{
eventRaiser = gcnew EventRaiser();
LPVOID lP = reinterpret_cast<LPVOID>(GCHandle::ToIntPtr(GCHandle::Alloc(eventRaiser)).ToPointer();
item = new UnmanagedItem(lP);
}
// some implementation
ref class EventRaiser : public ISpecificEventRaiser
{
virtual void fireAppDisconnect();
// other methods
};
EventRaiser^ eventRaiser;
UnmanagedItem* item;
};
public class UnmanagedItem
{
UnmanagedItem(LPVOID eventRaiser)
{
IEventRaiser^ r;
IntPtr pointer(eventRaiser);
handle = GCHandle::FromIntPtr(pointer);
r = safe_cast<IEventRaiser^>(handle.Target); // InvalidCastException : Unable to cast object of type 'EventRaiser' to type 'IEventRaiser'.
}
};
There should be no problem with casting to EventRaiser^ to IEventRaiser^, because i tried it before. Before trying to LPVOID conversations, it was working fine. But when i cast it into LPVOID and recast it to IEventRaiser, it throws InvalidCastException. How can i do the castings via LPVOID properly?

Reason to have a LPVOID pointer to my unmanaged class was to get rid of duplicate header imports. So, although i pay attention to included header files, IEventRaiser's header file was imported to inhereted project in some way. So, as Hans Passant indicated on comments, it causes a cast problem because of different assembly names. What i did to solve the problem is adding #ifdef statements to base project's IEventRaiser header file includes. Like the following:
#ifdef BASE_DLL
#include "IEventRaiser.h"
#endif
Then, i added to "BASE_DLL" to preprocessor definitions. It guarantees that the event raiser header will be included once. The other alternative was using forward declarations for not to add "IEventRaiser.h" header file to unmanaged file header. It's also tried and working.

Related

Static member used as default parameter leads to unresolved externals

I have a confusing issue using a static member variable as a default parameter. Since the same language construct works in a different place, it might be related to project (DLL) inter-dependencies. So please accept my apologies if my example is too complex, but I should draw the whole picture since I do not have any idea what is wrong.
I have a base class (representing kind of an error code)
ErrorBase.h
class ErrorBase
{
public:
typedef unsigned long ErrorCode;
/// here go the error codes. For reasons I do not want to explain, I cannot use an enumeration here.
static const ErrorCode ERROR_UNINITIALIZED;
static const ErrorCode ERROR_OK;
///...and so on
ErrorBase(ErrorCode theCode = ERROR_UNINITIALIZED);
};
...and in ErrorBase.cpp, I am assigning values to the codes...
const ErrorBase::ErrorCode ErrorBase::ERROR_UNINITIALIZED = 0xffffffff;
const ErrorBase::ErrorCode ErrorBase::ERROR_OK = 0x0;
//.. and so on...
ErrorBase is exported from a DLL which provides some general purpose classes to our project
Now I am deriving another error class for more specific errors which has additional attributes specific for the particular type of error. The class SpecificError is part of a different DLL which links to the general purpose DLL containing ErrorBase. I have not included the dllimport/dllexport shebang, but we are using this all over the place and it works in all cases. If you have doubts, I can edit my code example.
SpecificError.h
class SpecificError : public ErrorBase
{
public:
static const ErrorCode SPECIFIC_ERROR_UNINITIALIZED;
static const ErrorCode SPECIFIC_ERROR_SOMETHING_WENT_WRONG;
SpecificError(ErrorCode theCode = SPECIFIC_ERROR_UNINITIALIZED);
};
... and in the SpecificError.cpp I am defining these values:
const SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED = ErrorBase::ERROR_UNINITIALIZED;
Like ErrorBase, SpecificError is exported from the DLL handling specific functionality. Note that both error classes declare a constructor using the "UNINITIALIZED" value as a default for the error code.
Now I have a program being dependent on both DLLs, thus linking to both of them through the corresponding import libraries. This program includes ErrorBase.h and SpecificError.h. It does not seem to have any problems with ErrorCode.h, but about SpecificError.h I am receiving an
LNK2001 unresolved external symbol SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED referenced in main.obj.
(remark: main.cpp does not explicitly use SpecificError, it just includes the header file).
I was able to work-around the problem by removing the default parameter from the SpecificError constructor and declaring a default constructor which in its implementation calls the inherited constructor of ErrorBase passing SPECIFIC_ERROR_UNINITIALIZED to it. This leads me to the assumption that the symbol SPECIFIC_ERROR_UNINITIALIZED is properly declared and defined but cannot be used as a parameter default. However, this seems to apply to SpecificError only, everything seems fine in ErrorBase.
Toolset: I am using Visual C++ 2017 as a compiler.
I recreated the linked error. Make the following changes to your files and it should work just fine based on the code snippets that you showed above:
SpecificError.cpp
// I sent theCode to the Base class
SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{
// ...
}
In ErrorBase.cpp I just added the constructor but you probably already have this:
ErrorBase::ErrorBase(ErrorCode theCode)
{
// ...
}
After I did this, I had to also move the initializations of the static consts to the .h from the .cpp files. Then I tested the code by doing:
SpecificError e; // theCode ends up being 0xffffffff
SpecificError e1(20); // theCode ends up being 20
I hope that this helps you.
Here is what my ErrorBase.cpp looks like:
#pragma once
#include"ErrorBase.h"
#include<iostream>
ErrorBase::ErrorBase(ErrorCode theCode) {
std::cout << theCode << std::endl;
}
ErrorBase.h:
#pragma once
class ErrorBase
{
public:
typedef unsigned long ErrorCode;
static const ErrorCode ERROR_UNINITIALIZED = 0xffffffff;
static const ErrorCode ERROR_OK = 0x0;
ErrorBase(const ErrorCode = ERROR_UNINITIALIZED);
};
SpecificError.cpp:
#pragma once
#include"SpecificError.h"
SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{
}
SpecificError.h:
#pragma once
#include "ErrorBase.h"
class SpecificError : public ErrorBase
{
public:
static const ErrorCode SPECIFIC_ERROR_UNINITIALIZED = ErrorBase::ERROR_UNINITIALIZED;
static const ErrorCode SPECIFIC_ERROR_SOMETHING_WENT_WRONG = -42;
SpecificError(ErrorCode theCode = SPECIFIC_ERROR_UNINITIALIZED);
};
I tried this and it is working, the class name was missing in ErrorBase.cpp
const ErrorBase::ErrorCode ErrorBase::ERROR_UNINITIALIZED = 0xffffffff;
const ErrorBase::ErrorCode ErrorBase::ERROR_OK = 0x0;
If still not working then let me know.
You doing it wrong. The linker error means that it doesn't know where to get your constant value. You should use dynamic linkage with a first DLL. Let me show
Example of C++ class export:
C++ How to export a static class member from a dll?
And your code should be changed:
ErrorBase.h
#ifndef MAIN_DLL
#define MAIN_DLL 1 // or you can add MAIN_DLL definition to the your first project Macroses
#endif
#if MAIN_DLL
#define ERROR_API __declspec(dllexport) // export things to other modules
#else
#define ERROR_API __declspec(dllimport) // import things from the external DLL
#endif
class ERROR_API ErrorBase
{
public:
typedef unsigned long ErrorCode;
/// here go the error codes. For reasons I do not want to explain, I cannot use an enumeration here.
static const ErrorCode ERROR_UNINITIALIZED;
static const ErrorCode ERROR_OK;
///...and so on
ErrorBase(ErrorCode theCode = ERROR_UNINITIALIZED);
};
SpecificError.h
#pragma once
#define MAIN_DLL 0
#include "../Dll_stack_ovfl1/ErrorBase.h" // change it to your path
class SpecificError : public ErrorBase
{
public:
static const ErrorCode SPECIFIC_ERROR_UNINITIALIZED;
static const ErrorCode SPECIFIC_ERROR_SOMETHING_WENT_WRONG;
SpecificError(ErrorCode theCode = SPECIFIC_ERROR_UNINITIALIZED);
};
And the final step, configure the second DLL project to link it with exports of the first one:
Configuration Properties/Linker/Input/Additional dependencies
Add something like "$(SolutionDir)$(Configuration)\ErrorBase.lib"
Once again its just example, I don't know the real path of "lib" file and your project name for ErrorBase DLL - change it to your specific.

pre-defining classes not working when using pointers to classes

I am trying to implement a listener. Because of many cross-references I am trying to avoid including other classes and pre-define them
My listener looks as follows
.h
class Book
{
public:
Book();
private:
std::vector<MyListener *> listeners_;
void Notify();
}
.cpp
Book::Book() {}
void Book::Notify() {
MyListener *p_listener;
for ( int i = 0; i < this->listeners_.size(); i++ ) {
p_listener = listeners_[i];
p_listener->Update(); // ERRORS THROWN HERE WHEN NOT INCLUDING LISTENER.H
}
}
This all works fine when I include the listener.h file
#include "listener.h"
But when I instead pre-declare Listener it doesnt work
class Listener;
It gives me the two errors
C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2027: use of undefined type 'Listener'
C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2227: left of '->Update' must point to class/struct/union/generic type
Is there a way to avoid including the Listener header?
In the header file of class Book, you should indeed use a forward declaration of MyListener, as the header only defines an std::vector of pointers to MyListener and does not need to know the full declaration of MyListener.
The implementation file of class Book, however, actually needs the full declaration of MyListener, as it calls its update method, so you would include listener.h in the implementation file of class Book instead of in the header file.
Let's suppose the compiler sees the following code:
class Listener;
std::vector<Listener*> pListeners;
// some code...
for(auto& pListener: pListeners) {
pListener->update();
}
Note, how does the compiler see the Listener has a member function update? The symbol update could not be determined until the compiler see the Listener full declaration. Think if you used update with an argument missing, could the compiler capture this problem without seeing the declaration of update? Thus, it cannot translate the code. If you give a full declaration of the Listener, e.g.
class Listener {
public:
Listener() { // some construction
}
void update() {
// dosth
}
};
The compiler could know the update method, its parameters, the return value, etc., and compile it happily.

How to declare a new class in the header and define it in the source file without this errors?

I'm on the situation where I want to create a new class and then use it in another created class (C++), but without using different header or source files: both classes shall be in the same place, one way or another. The main class shall contain only a pointer to the "child" class.
Now I know that in many cases is perfectly possible to define a class in the header file. In fact, if one wants to not just set a pointer to that "child class", but actually use one of its methods already in the header file (e.g., for inline methods), one would actually have to define it in the source file:
class ChildClass
{
public:
bool myFunctions() { return true; }
}
class MainClass
{
private:
ChildClass* poChildClass;
inline bool getResult() { return poChildClass->myFunctions(); }
}
But let's suppose I want just to have that pointer there, without any call to my ChildClass' methods, so I should be able to only declare the ChildClass and later define it in the same .cpp file as MainClass is defined:
//in .hpp
class ChildClass;
class MainClass
{
private:
ChildClass* poChildClass;
}
//in .cpp
class ChildClass
{
public:
bool myFunctions() { return true; }
}
//etc.
In a first moment I don't know what could be there of a problem. But in trying to do so with one of my classes in particular (which is based on Qwt's QwtPlotPicker class), I get some compile errors (in this last version):
error: undefined reference to `vtable for Picker'
The error points out where in the following code (in the .cpp):
class Picker : public QwtPlotPicker
{
Q_OBJECT
public:
Picker( QWidget* canvas ) :
QwtPlotPicker( canvas ) //Here lies the error the compiler says
//...
So what is the problem? What do I get this "undefined reference to 'vtable'" problem?
Thanks for any help,
Momergil
This is a problem I have had forever when using QT. Any class that has the Q_OBJECT macro in it MUST be listed in the HEADERS before running qmake (as far as I can tell). This may even mean putting the .cpp file in the HEADERS section.

Class as library of global not const variables in cli c++

How should defined class where are only global variables?
I did something like that:
public ref class Klient
{
public:
Klient(){}
// zmienne
static array<DWORD,2>^ klienty = gcnew array<DWORD,2>(40,2);
static int i = 0;
static DWORD pid;
static HANDLE handle;
static String^ nick;
//funkcje
};
But if i include it more than 1 time it won't compile and showing redefinition of class error.
Did you guard your header? In Visual Studio, you should place this directive at the top of all header files:
#pragma once
This is equivalent to the classic C++ header guard:
#ifndef HEADER_SYMBOL_X
#define HEADER_SYMBOL_X
// class declarations go here
#endif // HEADER_SYMBOL_X
If you don't guard your header, C++/CLI will indeed try to redefine your class on each include.
You'll have to be a little more clear, and paste the error you get. Also if you have a "ref" class the compiler generates a default constructor for you, so you don't need to write one.
This code worked for me, I was able to fetch the static int value into my WPF application:
#pragma once
#include "windows.h"
using namespace System;
namespace cppcli
{
public ref class Klient
{
public:
static array<DWORD,2>^ klienty = gcnew array<DWORD,2>(40,2);
static int i = 22;
static DWORD pid;
static HANDLE handle;
static String^ nick;
};
}
Update:
Noticed your comment, yes you need #pragma once in there. I assumed it was there since it's generated automatically by Visual Studio, well good to know that it works :-)

Base class Undefined WEIRD problem . Need help

My CGameStateLogo which inherit from CGameState:
CGameState.h
#pragma once
#include "GameMain.h"
#include "MyBitmap.h"
class CGameMain;
class CMyBitmap;
class CGameState
{
public:
CMyBitmap* pbmCurrent;
CGameMain* pGM;
int GameStateID;
virtual void MessageEnter () = 0;
virtual void MessageUpdate( int iKey ) = 0;
virtual void MessagePaint( HDC* pDC ) = 0;
void StateHandler ( int msg, HDC* pDC, int key );
public:
CGameState(void);
~CGameState(void);
};
After creating and finding, problem comes from here :
I've created 2 classes: CTest and CGameStateLogo
#pragma once
#include "GameState.h"
class CTest:CGameState
{
public:
CTest(void);
~CTest(void);
};
#pragma once
#include "GameState.h"
class CGameStateLogo:CGameState // Bug at this line
{
public:
CGameStateLogo(void);
~CGameStateLogo(void);
};
Do VS has problem in naming ?
Thanks for reading this :). Things go WEIRD, I'll update my question later. Sorry for wasting your time .
pGameStates.push_back( (CGameState*)gameLogo );
Since CGameStateLogo inherits publically from CGameState, the cast is unneccesary. Upcasts are implicit. Simply write
pGameStates.push_back( gameLogo );
instead.
This does probably not solve your compile troubles, though. As to that, you seem to be mixing up GameState.h and CGameState.h. If that's an actual error in your code, instead of just a copy/paste mistake while writing your question, it could cause this problem.
It could also be that there is some circular dependency problem in your headers. You write
#include "GameState.h"
which should define the GameState class, unless the file has already been included once, but the class definition has not yet been read. This could happen for example in this way:
Some .cpp file includes GameState.h.
GameState.h includes GameMain.h.
GameMain.h includes GameStateLogo.h.
GameStateLogo.h includes GameState.h, but this has already been included, so the include is ignored due to #pragma once.
Generally, such circular dependencies in header files are a thing to avoid.
CGameStateLogo.h is including GameState.h and not CGameState.h. Is it possible you have a file called GameState.h on the include path (and hence you wouldn't get an error about not being able to include GameState.h)?