I created a dll with VS C++ (of course as a dll project) with the following code of the header file:
#pragma once
#include <iostream>
#include "..\..\profiles/ProfileInterface.h"
using namespace std;
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
public:
CExportCoordinator(void);
virtual ~CExportCoordinator(void);
CProfileInterface* Create();
void Initialize();
void Start();
};
Here is .cpp file of the dll:
#include "StdAfx.h"
#include "ExportCoordinator.h"
CExportCoordinator::CExportCoordinator(void)
{
}
CExportCoordinator::~CExportCoordinator(void)
{
}
CProfileInterface* CExportCoordinator::Create(){
cout << "ExportCoordinator3 created..." << endl;
return new CExportCoordinator();
}
void CExportCoordinator::Initialize(){
cout << "ExportCoordinator3 initialized..." << endl;
}
void CExportCoordinator::Start(){
cout << "ExportCoordinator3 started..." << endl;
}
I exported the whole class CExportCoordinator because I need to use all three methods it offers. Following is the code from the main application loading the, above given, dll on the fly.
typedef CProfileInterface* (WINAPI*Create)();
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hLib = LoadLibrary(name);
if(hLib==NULL) {
cout << "Unable to load library!" << endl;
return NULL;
}
char mod[MAXMODULE];
GetModuleFileName(hLib, (LPTSTR)mod, MAXMODULE);
cout << "Library loaded: " << mod << endl;
Create procAdd = (Create) GetProcAddress(hLib,"Create");
if (!procAdd){
cout << "function pointer not loaded";
}
return;
}
On the output I get that correct library is loaded, but that function pointer procAdd is NULL. I thought it had something to do with name mangling and added extern "C" when exporting the class in header of dll, but nothing changed. Btw, I used dll export viewer for viewing the exported functions of the class, and the whole class is exported correctly.
Any help?
UPDATE
there is an error in the header file of dll. I shouldn't be using extern "C" __declspec(dllexport) before class because then class won't be exported at all. If I use class __declspec(dllexport) CExportCoordinator then the class is exported correctly, but anyway I can't get the address of the function other than NULL.
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
This is nonsense. A class cannot be "extern C"
... inside the class ...
CProfileInterface* Create();
This creates a member function of the class, which is not probably what you want. For one thing, it will be mangled in the DLL, second, it will not be callable without the this pointer. Probably, you need this declaration:
extern "C" __declspec(dllexport) CProfileInterface* Create();
and implemntation:
extern "C" __declspec(dllexport) CProfileInterface* Create(){
cout << "ExportCoordinator3 created..." << endl;
return new CExportCoordinator();
}
It seems to me that you should declare Create method as a static method and export this method only. If you will stay have NULL in GetProcAddress you should examine exports of your DLL with respect of Dependency Walker (see http://www.dependencywalker.com/) and modify the name of the function "Create" to something like "_Create" or "_Create#2".
Related
I have the following code:
#include <iostream>
template <typename T>
void foo(const T& v) { //version 1
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void foo(char* v) {//version 2
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void foo(const char* v) {//version 3
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main() {
char s1[] = "1234";
const char* s2 = "2345";
foo(s1);
foo(s2);
}
The output is:
void foo(char*)
void foo(const char*)
I thought s1 needs to go through pointer decay and so the template function foo() is a better match.
If I remove the 2nd foo()'s declaration and definition, then compiler chooses not to go through pointer decay and chooses the template function foo().
Now, I am confused what the rule is for compiler to choose which function to bind to/call.
Thanks!
That behavior is governed by overload resolution rules, which are quite complicated. A good write-up can be found here: https://en.cppreference.com/w/cpp/language/overload_resolution
For your particular case, a non-template function foo(char* ) with implicit conversion wins over template function.
I cannot serialize boost::rational<int>. I searched for a boost/serialize/rational.h header but it does not exist.
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class boost::rational<int>’ has no member named ‘serialize’
Is there a way to achieve it?
Just serialize the numerator and denominator.
Here's the legwork, in semi-generic form (supports archives with named nodes, like XML serialization, too): Live On Coliru
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/rational.hpp>
#include <iostream>
namespace boost { namespace serialization {
template <typename Archive, typename T>
void save(Archive& ar, ::boost::rational<T> const& r, unsigned /*version*/)
{
int n = r.numerator(), d = r.denominator();
ar & boost::serialization::make_nvp("numerator", n);
ar & boost::serialization::make_nvp("denominator", d);
}
template <typename Archive, typename T>
void load(Archive& ar, ::boost::rational<T>& r, unsigned /*version*/)
{
int n, d;
ar & boost::serialization::make_nvp("numerator", n);
ar & boost::serialization::make_nvp("denominator", d);
r = ::boost::rational<T>(n, d);
}
} }
BOOST_SERIALIZATION_SPLIT_FREE(boost::rational<int>);
using namespace boost;
#include <iostream>
#include <sstream>
int main()
{
rational<int> number(2, 3), other;
std::stringstream ss;
{
archive::xml_oarchive oa(ss);
oa << serialization::make_nvp("rational", number);
}
std::cout << "Serialized: '" << ss.str() << "'\n";
{
archive::xml_iarchive ia(ss);
ia >> serialization::make_nvp("rational", other);
}
std::cout << "Deserialized: " << other;
}
Prints
Serialized: '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<rational class_id="0" tracking_level="0" version="0">
<numerator>2</numerator>
<denominator>3</denominator>
</rational>
</boost_serialization>
'
Deserialized: 2/3
Use the provided input/output functions: https://www.boost.org/doc/libs/1_64_0/libs/rational/rational.html#Input%20and%20Output
Serialize to a std::string:
template <typename I>
std::string serialize(boost::rational<I>& rational) const {
std::stringstream rational_ss;
rational_ss << rational;
return rational_ss.str();
}
This serializes the rational to a string that looks like "3/5" e.g.
To deserialize, use boost::rational's >>.
I'm not able to make this code work using fellowed convention of header includes.
help.cpp
#include <iostream>
#include "basicMath.h"
using namespace std;
int main() {
int arr[4]={0,1,2,3};
int k=0;
int m=3;
//permutations call
perm(arr,k,m);
return 0;
}
BasicMath.h
#ifndef BASICMATH_H_
#define BASICMATH_H_
template<class T>
void Swap ( T& a, T& b );
template<class T1>
void perm ( T1 arr[], int k, int m);
#endif /* BASICMATH_H_ */
BasicMath.cpp
#include <iostream>
#include "basicMath.h"
using namespace std;
template<class T>
void Swap ( T& a, T& b )
{
T temp;
b=temp;
b=a;
a=temp;
}
template<class T1>
void perm ( T1 arr[], int k, int m)
{
//base case
cout << "Call: " << arr[0] << arr[1] << arr[2] << arr[3] << "\t" << k << "\t" << m << "\n";
if (k==m) {
for (int i=0;i<=m;i++) {
cout << arr[i];
}
cout << endl;
} else {
for (int i=k;i<=m;i++) {
swap(arr[k],arr[i]);
perm(arr,k+1,m);
swap(arr[k],arr[i]);
}
}
}
IF I replace the #include "basicMath.h" by #include "basicMath.cpp" Then program works.
Please help. New to Eclipse Project using headers and src.
Thanks in Adv.
The "simple" answer is that you can't put the implementation of a template function into a .cpp file.
See http://www.parashift.com/c++-faq/templates-defn-vs-decl.html
For boost::serialize I am trying to define a custom class with its own serialize function, similar to http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/tutorial.html#simplecase However, the program just segfaults. Why?
class Test {
public:
unsigned short testid;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & testid;
}
};
int main() {
Test mytest = {100};
std::ofstream ofsx("test.tmp");
boost::archive::binary_oarchive oax(ofsx);
oax << mytest;
cout << "Exported";
exit(1);
}
I also tried the non-intrusive version with the same result.
Am I missing something?
The problem was caused by linking against outdated libraries.
What are they, what's the different between them?
Many sources, like Wikipedia, claim they're the same thing, but others explicitly say the opposite, like sbi in this question:
First: "Visitor Pattern is a way to simulate Double Dispatching in C++." This is, erm, not fully right. Actually, double dispatch is one form of multiple dispatch, which is a way to simulate (the missing) multi-methods in C++.
They are the same.
When you call a virtual method in C++, the actual method to run is based on the runtime type of the object them method is invoked on. This is called "single dispatch" because it depends on the type of a single argument (in this case, the implicit 'this' argument). So, for example, the following:
class Base {
public:
virtual int Foo() { return 3; }
}
class Derived : public Base {
public:
virtual int Foo() { return 123; }
}
int main(int argc, char *argv[]) {
Base* base = new Derived;
cout << "The result is " << base->Foo();
delete base;
return 0;
}
When run, the above program prints 123, not 3. So far so good.
Multiple-dispatch is the ability of a language or runtime to dispatch on both the type of the 'this' pointer and the type of the arguments to the method. Consider (sticking with C++ syntax for the moment):
class Derived;
class Base {
public:
virtual int Foo(Base *b) { cout << "Called Base::Foo with a Base*"; }
virtual int Foo(Derived *d) { cout << "Called Base::Foo with a Derived*"; }
}
class Derived : public Base {
public:
virtual int Foo(Base *b) { cout << "Called Derived::Foo with a Base*"; }
virtual int Foo(Derived *d) { cout << "Called Derived::Foo with a Derived*"; }
}
int main(int argc, char *argv[]) {
Base* base = new Derived;
Base* arg = new Derived;
base->Foo(arg);
delete base;
delete arg;
return 0;
}
If C++ had multiple-dispatch, the program would print out "Called Derived::Foo with a Dervied*". (Sadly, C++ does not have multiple-dispatch, and so the program prints out "Called Derived::Foo with a Base*".)
Double-dispatch is a special case of multiple-dispatch, often easier to emulate, but not terribly common as a language feature. Most languages do either single-dispatch or multiple-dispatch.