I am trying to load a class defined in a .dll file. However there are two slightly different ways of defining the class in the dll. I'm not sure which is the more legit way to do it, and I don't know why the second way also works. Here is a simple example:
Method 1:
In main.cpp:
#include <iostream>
#include <windows.h>
#include <memory>
#include "bar.h"
using namespace std;
typedef bar* (* MYDLLPROC)();
int main()
{
unique_ptr<bar> theresult;
auto thelib = LoadLibrary(TEXT("foo.dll"));
if (thelib != NULL) {
MYDLLPROC theprocs = (MYDLLPROC)GetProcAddress(thelib, "Myfoo");
cout << "load successfully" << endl;
theresult.reset(theprocs());
theresult->printmsg();
} else {
cout << "cannot load the dll" << endl;
}
return 1;
}
The bar is defined as a pure virtual class in bar.h:
class bar {
public:
virtual ~bar() {};
virtual void printmsg() = 0;
};
In the foo.dll source file:
#include <iostream>
#include <windows.h>
#include "bar.h"
using namespace std;
class foo: public bar {
public:
foo() { cout << "foo is instantiated" << endl; }
~foo() {}
void printmsg() final { cout << "msg from foo print" << endl; }
};
extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
return new foo();
}
In the first method the pure virtual class bar is used as an interface, and it makes sense that its member function(s) is overridden by that in foo when the dll is loaded.
However, I found that foo doesn't have to be derived from bar, everything still works as long as foo has a Vtable:
In the second method, everything is the same except for the definition of foo:
#include <iostream>
#include <windows.h>
using namespace std;
class foo {
public:
foo() { cout << "foo is instantiated" << endl; }
virtual ~foo() {}
virtual void printmsg() final { cout << "msg from foo print" << endl; }
};
extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
return new foo();
}
Could anyone please let me know why the second method works? I'm a bit confused because foo and bar are not related but the member function in bar can still be overridden.
So you cast a function returning foo* as a function returning bar* and then invoking it.
The end result is that you have a pointer to foo which is a pointer to an unrelated type bar. Using it in any way will lead to undefined behavior.
It appears to work in this specific case because the position of the printmsg virtual function in both vtables is the same, so invoking bar::printmsg on an instance of foo simply calls the "Nth entry in the vtable". If you add another virtual member to foo before printmsg, then it might get called instead (or the program might crash).
First example is very fragile because it implicitly relies on foo and bar being pointer-interchangeble.
Second example is broken because function Myfoo returns a pointer to class foo that is not related to bar and dereferencing it causes undefined behavior.
Function signature must match the function implemented in the dll. What you have right now is basically a wild reinterpret_cast from foo * to bar *.
Related
I have a main.cpp file, with #include "engine.h" in the beginning.
Inside engine.h there's
#include "myObject.h"
namespace nmspc{
MyObject obj1;
//some code here
}
and myObject.h has:
#include <iostream>
class MyObject{
public:
void helloWorld(){
std::cout << "Hello, World!" << std::endl;
}
}
Why can't I refer have in my main.cpp something like this?:
int main{
nmspc::obj1::helloWorld();
return 0;
}
instead I have to type either nmspc::obj1.helloWorld(), or MyObject::helloWorld(). But I'd like to use the one above.
You can do something like this using static member functions, by adding the keyword static before the method declaration. if you do this, the function will not be associated with an actual instantiation of the class, so cannot access any member variables or non-static member functions.
In general, you wouldn't access static member functions through the created object, but through the class name (although it is possible to call it through an instance).
class MyObject{
public:
static void helloWorld() {
std::cout << "Hello, World!" << std::endl;
}
}
int main{
MyObject::helloWorld();
return 0;
}
Whether or not you should do this is dependant on the context. Your program is simple enough that's its not immediately clear why you would make it a static member function, rather than a free function, but I'm not sure I have enough context to give advice.
1st of all
incorrect header content
#include "myObject.h"
namespace nmspc{
MyObject obj1;
//some code here
}
this should be in a cpp module i.e: a translation unit
as it is an instantiation i.e. a dynamic related thing (run time affect code)
whereas header is the place for all of the static related content
if like to write MyObject::helloWorld()
may have it here
myObject.h :
#include <iostream>
namespace nmspc{
class MyObject{
public:
void helloWorld();
};
MyObject::helloWorld(){
std::cout << "Hello, World!" << std::endl;
}
}
because :: (scope resolution op.) is what name space or class/struct referred to
e.g. nmspc::MyObject::helloWorld
might be helloWorld class inside MyObject class belong to nmspc name space
might be helloWorld class belong to MyObject name space belong to nmspc name space. etc
int main{
MyObject obj1;
//some code here
nmspc::obj1.helloWorld();
return 0;
}
I got two classes separated in four files. The main class includes a sub class and needs to execute functions of it (not shown in the minimal example code). What I want to do is to execute a function of the main class in the scope of the subclass.
I think some ideas would be to inherit the functions in the sub class but I could not figure out how to do this.
MainClass.cpp
#include "MainClass.hpp"
void MainClass::mainCallback() {
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback() {
std::cout << "[subCallback] executed" << std::endl;
}
int main() {
MainClass mainClass;
mainClass.mainCallback();
SubClass subClass;
subClass.activateSubClass();
return 0;
}
MainClass.hpp
#pragma once
#include "SubClass.hpp"
#include <iostream>
class MainClass{
public:
void mainCallback();
void subCallback();
};
SubClass.cpp
#include "SubClass.hpp"
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
SubClass.hpp
#pragma once
class SubClass{
public:
void activateSubClass();
};
The error in SubClass.cpp is of course:
error: use of undeclared identifier 'mainClass'
Just subclass the subclass:
class SubClass: public MainClass {
public:
void activateSubClass();
};
This (public) way the SubClass makes all methods of MainClass callable in SubClass instances. You could also private inherit. That way only activateSubClass() 'ld be callable.
In activateSubClass you can call directly the methods of the parent class:
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
Don't forget to include MainClass.hpp in SubClass.hpp
You try to call a MainClass.subCallback() without having an instance of MainClass. According to me, this is the typical use case for static methods.
Then, I think you make your #include directives the wrong way. Indeed, MainClass does not seem to need to know SubClass but the opposite is true. I think it is better to include MainClass.hpp in SubClass.hpp. This will solve your circle dependencies problem.And you can write your main() function in another file.
EDIT: Example
MainClass.hpp:
#pragma once
class MainClass
{
public:
void mainCallback();
static void subCallback(); // mak it static to be able to call it without an instance of the class
};
MainClass.cpp:
#include "MainClass.hpp"
#include <iostream>
void MainClass::mainCallback()
{
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback()
{
std::cout << "[subCallback] executed" << std::endl;
}
SubClass.hpp:
#pragma once
class SubClass
{
public:
void activateSubClass();
};
SubClass.cpp:
#include "SubClass.hpp"
#include "MainClass.hpp" // MainClass inclusion
void Suclass::activateSubClass()
{
MainClass::subCallback(); // Call of the static method
}
main.cpp:
#include "MainClass.hpp"
#include "SubClass.hpp"
int main()
{
MainClass mc;
mc.mainCallback();
SubClass sc;
sc.activateSubClass(); // Will call MainClass::subCallback()
return 0;
}
I hope it can help you.
Background
Recently, a colleague of mine ran into a problem where an old version of a header file for a library was used. The result was that the code generated for calling a virtual function in a C++ referred to the wrong offset in the virtual function lookup table for the class (the vtable).
Unfortunately, this error was not caught during compilation.
Question
All ordinary functions are linked using their mangled names which ensures the correct function (including the correct overload variant) is selected by the linker. Likewise, one could imagine that an object file or a library could contain symbolic information about the functions in the vtable for a C++ class.
Is there any way to let the C++ compiler (say g++ or Visual Studio) type check calls to virtual function during linking?
Example
Here is a simple test example. Imagine this simple header file and the associated implementation:
Base.hpp:
#ifndef BASE_HPP
#define BASE_HPP
namespace Test
{
class Base
{
public:
virtual int f() const = 0;
virtual int g() const = 0;
virtual int h() const = 0;
};
class BaseFactory
{
public:
static const Base* createBase();
};
}
#endif
Derived.cpp:
#include "Base.hpp"
#include <iostream>
using namespace std;
namespace Test
{
class Derived : public Base
{
public:
virtual int f() const
{
cout << "Derived::f()" << endl;
return 1;
}
virtual int g() const
{
cout << "Derived::g()" << endl;
return 2;
}
virtual int h() const
{
cout << "Derived::h()" << endl;
return 3;
}
};
const Base* BaseFactory::createBase()
{
return new Derived();
}
}
Now, imagine that a program uses a wrong/old version of the header file where the virtual function in the middle is missing:
BaseWrong.hpp
#ifndef BASEWRONG_HPP
#define BASEWRONG_HPP
namespace Test
{
class Base
{
public:
virtual int f() const = 0;
// Missing: virtual int g() const = 0;
virtual int h() const = 0;
};
class BaseFactory
{
public:
static const Base* createBase();
};
}
#endif
So here we have the main program:
Main.cpp
// Including the _wrong_ version of the header!
#include "BaseWrong.hpp"
#include <iostream>
using namespace std;
int main()
{
const Test::Base* base = Test::BaseFactory::createBase();
const int fres = base->f();
cout << "f() returned: " << fres << endl;
const int hres = base->h();
cout << "h() returned: " << hres << endl;
return 0;
}
When we compile the “library” using the correct header and then compile and link the main program using the wrong header…
$ g++ -c Derived.cpp
$ g++ Main.cpp Derived.o -o Main
…then the virtual call to h() uses the wrong index in the vtable so the call actually goes to g():
$ ./Main
Derived::f()
f() returned: 1
Derived::g()
h() returned: 2
In this small example the functions g() and h() have the same signature so the “only” thing that goes wrong is the wrong function being called (which is bad in itself and could go completely unnoticed), but if the signatures are different this can (and has seen to) lead to stack corruption – e.g., when calling a function in a DLL on Windows where Pascal calling convention is used (caller pushes arguments and callee pops them before returning).
The short answer to your question is no. The fundamental problem is that the offsets to called functions are calculated at compile-time; therefore if your caller code was compiled with the (incorrect) header file that included "virtual int g() const", then your main.o will have all references to h() offset by the presence of g(). But your library has been compiled with the correct header file, therefore there is no function g(), thus the offset of h() in Derived.o will be different than in main.o
It's not a matter of typechecking calls to virtual functions - this is a "limitation" based on the fact that the C++ compiler does compile-time function offset calculation, and not runtime.
You can able to get around this problem by using dl_open instead of direct function calls and dynamically linking your library, instead of statically linking it.
Is it possible to call foo() function from Foo.cpp
without changing function name Foo::foo() to Foo::newfoo().
main.cpp
#include <iostream>
#include "Foo.hpp"
class Foo {
public:
void foo() {
std::cout << "Foo::foo\n";
}
void bar() {
std::cout << "Foo::bar\n";
foo();// need to call foo() function from foo.cpp not Foo::foo()
}
};
int main () {
Foo f;
f.bar();
return 0;
}
Foo.hpp
#ifndef FOO_HPP_INCLUDED
#define FOO_HPP_INCLUDED
void foo();
#endif // FOO_HPP_INCLUDED
Foo.cpp
#include "Foo.hpp"
#include <iostream>
void foo(){
std::cout << "foo\n";
}
ps.sorry for my poor english.
Use fully qualified name of the free function.
::foo();
The :: in front of the function name, tells the compiler to call the function by the name foo() that is in the global scope.
If the free function foo() was in some other namespace you need to use fully qualified name specifying the namespace.
namespacename::foo();
If the free function foo is defined in some namespace xyz, then do this:
xyz::foo(); //if foo is defined in xyz namespace
or else just do this:
::foo(); //if foo is defined in the global namespace
This one assumes foo is defined in the global namespace.
It is better to use namespace for your implementation. Avoid polluting the global namespace.
I am trying to call another function, foo(), in the Raw class from main.cpp but I keep on getting this error and I do not understand what is wrong with my code. I am working in C++, and I am using the QT framework. I am new to this language and framework.
Error:
LNK2019: unresolved external symbol "public:void __thiscall RAW::foo(void)" (?foo#Raw##QAEXXZ) referenced in function_main. File not found:main.obj
main.cpp
#include "raw.h"
using namespace std;
int main(int, char*)
{
Raw newRaw;
newRaw.foo();
return 0;
}
raw.cpp
#include "raw.h"
#include <iostream>
using namespace std;
void foo()
{
cout << "hi\n";
}
Raw::Raw()
{
cout << "raw\n";
}
raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
#endif // RAW_H
In raw.cpp you have to define foo like this:
void Raw::foo()
{
cout << "hi\n";
}
You have to put Raw:: so that the compiler knows that this is the class member function foo and not some other independent function.
As Mihai was saying, you can also define it in the Header file (.h/.hpp), but that is considered bad practice if your class method is complex in any way.
class Raw {
public:
void foo() {
cout << "hi\n";
}
};
Only time you should really ever do this is for extremely simple classes and for methods that are nothing more than getters really.
You should understand the difference between defining and declaring something in C++.
Declaring is to simply make a prototype, for example void doSomething(int); is a valid declaration as it says that the method doSomething takes an int and returns void.
Now, you need to describe what it does. This is the definition when you do void doSomething(int val) { cout << val << endl; } as you are now describing what to do with that function.
You can make the definition in the header file, as I showed, or in the source file (.c/.cpp) as Mihai showed (which is best practice). You can only make your declarations in the Header file, though.
Ok, this are some alternatives:
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo(){cout << "raw\n";}
};
or
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
Raw::Raw()
{
cout << "raw\n";
}
In both cases you won't need the implementation in raw.cpp anymore. But as I said before, my first solution is standard c++ practice.