LNK2019 constructor/destructor using C++ Dll - c++

I am developping a C++ DLL with a C wrapper in order to use it in Python and C#. So I create on Visual Studio a project (DLL) to develop and compile it. No problem here. I even can use my DLL on Python without trouble.
But, on Visual, I want to create another project in the same solution as the DLL to test the DLL too.
So I created the second project (Win32 Windows Application), added the .h to the header files, added the link to the .lib file I added in the folder of the test project, but when I try to compile it, I have errors about LNK2019, beginning with the constructor:
error LNK2019: unresolved external symbol "public: __cdecl Projet::Projet(void)" (??Projet##QEAA#XZ) referenced in function main
DLL = Projet / Test = Projet_Test
Projet.h
#pragma once
#include "Projet_inc.h"
class Projet
{
public:
Projet();
~Projet();
int multiply(int arg1, int arg2);
int result;
};
Projet_inc.h
#ifdef PROJET_EXPORTS
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
#define CALLCONV_API __stdcall
#ifdef __cplusplus
extern "C" // C wrapper
{
#endif
typedef struct Projet Projet; // make the class opaque to the wrapper
EXPORT Projet* CALLCONV_API cCreateObject(void);
EXPORT int CALLCONV_API cMultiply(Projet* pDLLobject, int arg1, int arg2);
#ifdef __cplusplus
}
#endif
Projet.cpp
#include "stdafx.h"
#include "Projet.h"
Projet::Projet() {}
Projet::~Projet() {}
int Projet::multiply(int arg1, int arg2) {
result = arg1 * arg2;
return result;
}
Projet* EXPORT CALLCONV_API cCreateObject(void)
{
return new Projet();
}
int EXPORT CALLCONV_API cMultiply(Projet* pDLLtest, int arg1, int arg2)
{
if (!pDLLtest)
return 0;
return pDLLtest->multiply(arg1, arg2);
}
Projet_Test.cpp
// Projet_Test.cpp : définit le point d'entrée pour l'application console.
//
#include "stdafx.h"
#include "Projet.h"
int main()
{
Projet object;
return 0;
}
On Visual, I select the test project as startup project for information. And I look a lot of posts on SO but I didn't find the solution for now. Thank you in advance.

You need to __declspec(dllexport) all functions that you want to call directly, not just the C ones.
In your example, you should be able to correctly call the C wrapper functions cCreateObject and cMultiply, as those were exported correctly, but you will not be able to call the underlying C++ functions like Projet::Projet() and Projet::~Projet().
You have two ways of solving this: You can change these functions to inline functions and move their implementation to the header. That way, the client project will no longer invoke the code from the DLL for those functions, but instead just compile the inline definitions directly itself. This is obviously not a sensible approach in general. Alternatively, mark your C++ member functions with __declspec(dllexport), just as you did with the C functions.
Note that Visual Studio has a tendency of breaking the C++ ABI between versions, so you need to make sure that the compiler version you used for compiling the dll is compatible with the one you used for compiling the client application. This is not an issue if both parts are compiled with the same Visual Studio version or if you stick with a plain C interface.

First, the error about the missing symbol EpsCndCoreDll seems to be out of context here and you should rather be getting a compile error about redefining struct as a class (class Projet).
Probably you need to use something like:
class Projet;
typedef Projet* PProjet;
and use PProject as the opaque handle further on.
You also need to export the Projet class like:
class EXPORT Projet
to be able to instantiate that class by a client or add a factory function that returns a reference.

Make sure that you have added the DLL reference to your DLL.

Related

dll: how to make a dll with some cpp classes [duplicate]

Most of my C/C++ development involves monolithic module files and absolutely no classes whatsoever, so usually when I need to make a DLL with accessible functions I just export them using the standard __declspec(dllexport) directive. Then access them either dynamically via LoadLibrary() or at compile time with a header and lib file.
How do you do this when you want to export an entire class (and all it's public methods and properties)?
Is it possible to dynamically load that class at runtime and if so, how?
How would you do it with a header and lib for compile time linking?
What about late-binding? As in loading
it with LoadLibrary() and
GetProcAddress() ? I'm used being able
to load the library at run time and it
would be great if you could do that
here.
So there are two ways to load the DLL. The first is to reference one or more symbols from the DLL (your classname, for example), supply an appropriate import .LIB and let the linker figure everything out.
The second is to explicitly load the DLL via LoadLibrary.
Either approach works fine for C-level function exports. You can either let the linker handle it or call GetProcAddress as you noted.
But when it comes to exported classes, typically only the first approach is used, i.e., implicitly link to the DLL. In this case the DLL is loaded at application start time, and the application fails to load if the DLL can't be found.
If you want to link to a class defined in a DLL, and you want that DLL to be loaded dynamically, sometime after program initiation, you have two options:
Create objects of the class using a special factory function, which internally will have to use (a tiny bit of) assembler to "hook up" newly created objects to their appropriate offsets. This has to be done at run-time AFTER the DLL has been loaded, obviously. A good explanation of this approach can be found here.
Use a delay-load DLL.
All things considered... probably better to just go with implicit linking, in which case you definitely want to use the preprocessor technique shown above. In fact, if you create a new DLL in Visual Studio and choose the "export symbols" option these macros will be created for you.
Good luck...
When you build the DLL and the module that will use the DLL, have some kind of #define that you can use to distinguish between one and the other, then you can do something like this in your class header file:
#if defined( BUILD_DLL )
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif
class IMPORT_EXPORT MyClass {
...
};
Edit: crashmstr beat me to it!
Adding a simple working example for exporting a C++ class from a DLL :
The given below example gives you only a short overview of how dll and exe can interact each other (self explanatory ) but it needs more things to add for changing into a production code.
Full sample example is divided in to two part
A. Creating a .dll library (MyDLL.dll)
B. Creating an Application which uses .dll library (Application).
A. .dll project file (MyDLL.dll):
1. dllHeader.h
#ifdef MYDLL_EXPORTS
#define DLLCALL __declspec(dllexport) /* Should be enabled before compiling
.dll project for creating .dll*/
#else
#define DLLCALL __declspec(dllimport) /* Should be enabled in Application side
for using already created .dll*/
#endif
// Interface Class
class ImyMath {
public:
virtual ~ImyMath() {;}
virtual int Add(int a, int b) = 0;
virtual int Subtract(int a, int b) = 0;
};
// Concrete Class
class MyMath: public ImyMath {
public:
MyMath() {}
int Add(int a, int b);
int Subtract(int a, int b);
int a,b;
};
// Factory function that will return the new object instance. (Only function
// should be declared with DLLCALL)
extern "C" /*Important for avoiding Name decoration*/
{
DLLCALL ImyMath* _cdecl CreateMathObject();
};
// Function Pointer Declaration of CreateMathObject() [Entry Point Function]
typedef ImyMath* (*CREATE_MATH) ();
2. dllSrc.cpp
#include "dllHeader.h"
// Create Object
DLLCALL ImyMath* _cdecl CreateMathObject() {
return new MyMath();
}
int MyMath::Add(int a, int b) {
return a+b;
}
int MyMath::Subtract(int a, int b) {
return a-b;
}
B. Application Project which load and link the already created .dll file:
#include <iostream>
#include <windows.h>
#include "dllHeader.h"
int main()
{
HINSTANCE hDLL = LoadLibrary(L"MyDLL.dll"); // L".\Debug\MyDLL.dll"
if (hDLL == NULL) {
std::cout << "Failed to load library.\n";
}
else {
CREATE_MATH pEntryFunction = (CREATE_MATH)GetProcAddress(hDLL,"CreateMathObject");
ImyMath* pMath = pEntryFunction();
if (pMath) {
std::cout << "10+10=" << pMath->Add(10, 10) << std::endl;
std::cout << "50-10=" << pMath->Subtract(50, 10) << std::endl;
}
FreeLibrary(hDLL);
}
std::cin.get();
return 0;
}
I use some macros to mark the code for import or export
#ifdef ISDLL
#define DLL __declspec(dllexport)
#endif
#ifdef USEDLL
#define DLL __declspec(dllimport)
#endif
Then declare the class in a header file:
class DLL MyClassToExport { ... }
Then #define ISDLL in the libary, and USEDLL before including the header file in the place you want to use the class.
I don't know if you might need to do anything differently for working with LoadLibrary
Recently I asked myself exactly the same question, and summarized my findings in a blog post. You may find it useful.
It covers exporting C++ classes from a DLL, as well as loading them dynamically with LoadLibrary, and discusses some of the issues around that, such as memory management, name mangling and calling conventions.
If you're willing to put a vtable in the class you're exporting, you can export a function that returns an interface and implement the class in the .dll, then put that in the .def file. You might have to do some declaration trickery, but it shouldn't be too hard.
Just like COM. :)

Calling a statically-linked static method in C++

I'm trying to call a statically-linked static method of a C++ class, but I'm getting the VS linker error LNK2019, "unresolved external symbol". Here's the library source:
// in header file
#define DllExport __declspec (dllexport)
class MyClass{
public:
DllExport
static HWND WINAPI myFunc();
};
// in cpp file
DllExport
HWND WINAPI MyClass::myFunc(){ /* create a GUI window that has instance of MyClass set as its property (using ::SetProp) */ }
myFunc is to serve as an entry point for creating objects of MyClass, which resides hidden in the library. Only such static functions can be used to influence the functionality of a MyClass instance (by providing the corresponding HWND).
Here's the library consumer:
#define DllImport __declspec(dllimport)
DllImport
HWND WINAPI myFunc();
...
int main(){
HWND hWnd=myFunc();
... // work with the window and attached MyClass instance
}
(I believe) all file linkages are set correctly - originally, myFunc was designed as a standalone function and all worked just fine. I suspect it must be some calling convetion mismatch that makes the linker produce the error on myFunc.
Read through multiple articles on this topic, namely
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
and
https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
but they didn't solve my problem.
Thanks for a suggestion!
Since your goal is to create static library, the first thing we want to do is eliminate any mention of dllexport/dllimport. Such specifiers are only used when you actually create a DLL project.
So for lib.h, we only need this (with some include guards added for good measure):
// lib.h
#ifndef LIB_H
#define LIB_H
class MyClass{
public:
static void myFunc();
};
#endif
The WINAPI specification is also unnecessary since you're the one calling the method and can just use the default calling convention without ABI issues (though if you do want to use WINAPI anyway, then you need to include <windows.h> in your header file).
For lib.cpp, we only need this:
// lib.cpp
#include <Windows.h>
#include "lib.h"
void MyClass::myFunc(){
::MessageBox(0,"myFunc call!",NULL,0);
}
For main.cpp in your app project, we only need this:
// main.cpp
#include <iostream>
#include <D:\staticlink\lib\lib.h>
int main(){
std::cout << "ahoj";
MyClass::myFunc();
char buf[10];
std::cin >> buf;
return 0;
}
I'd recommend configuring your include paths to find lib.h through your project settings instead of using absolute paths in your source code, but perhaps you can do that later after you get everything working.
After that, if a problem remains, the only thing you should need to ensure is that your app project is linking against lib.lib properly (linker settings).
Your import header file should look more like:
#define DllApi __declspec (dllexport)
class MyClass{
public:
DllApi
static HWND WINAPI myFunc();
};

how to transform my c++ for exe to a code for dll [duplicate]

Most of my C/C++ development involves monolithic module files and absolutely no classes whatsoever, so usually when I need to make a DLL with accessible functions I just export them using the standard __declspec(dllexport) directive. Then access them either dynamically via LoadLibrary() or at compile time with a header and lib file.
How do you do this when you want to export an entire class (and all it's public methods and properties)?
Is it possible to dynamically load that class at runtime and if so, how?
How would you do it with a header and lib for compile time linking?
What about late-binding? As in loading
it with LoadLibrary() and
GetProcAddress() ? I'm used being able
to load the library at run time and it
would be great if you could do that
here.
So there are two ways to load the DLL. The first is to reference one or more symbols from the DLL (your classname, for example), supply an appropriate import .LIB and let the linker figure everything out.
The second is to explicitly load the DLL via LoadLibrary.
Either approach works fine for C-level function exports. You can either let the linker handle it or call GetProcAddress as you noted.
But when it comes to exported classes, typically only the first approach is used, i.e., implicitly link to the DLL. In this case the DLL is loaded at application start time, and the application fails to load if the DLL can't be found.
If you want to link to a class defined in a DLL, and you want that DLL to be loaded dynamically, sometime after program initiation, you have two options:
Create objects of the class using a special factory function, which internally will have to use (a tiny bit of) assembler to "hook up" newly created objects to their appropriate offsets. This has to be done at run-time AFTER the DLL has been loaded, obviously. A good explanation of this approach can be found here.
Use a delay-load DLL.
All things considered... probably better to just go with implicit linking, in which case you definitely want to use the preprocessor technique shown above. In fact, if you create a new DLL in Visual Studio and choose the "export symbols" option these macros will be created for you.
Good luck...
When you build the DLL and the module that will use the DLL, have some kind of #define that you can use to distinguish between one and the other, then you can do something like this in your class header file:
#if defined( BUILD_DLL )
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif
class IMPORT_EXPORT MyClass {
...
};
Edit: crashmstr beat me to it!
Adding a simple working example for exporting a C++ class from a DLL :
The given below example gives you only a short overview of how dll and exe can interact each other (self explanatory ) but it needs more things to add for changing into a production code.
Full sample example is divided in to two part
A. Creating a .dll library (MyDLL.dll)
B. Creating an Application which uses .dll library (Application).
A. .dll project file (MyDLL.dll):
1. dllHeader.h
#ifdef MYDLL_EXPORTS
#define DLLCALL __declspec(dllexport) /* Should be enabled before compiling
.dll project for creating .dll*/
#else
#define DLLCALL __declspec(dllimport) /* Should be enabled in Application side
for using already created .dll*/
#endif
// Interface Class
class ImyMath {
public:
virtual ~ImyMath() {;}
virtual int Add(int a, int b) = 0;
virtual int Subtract(int a, int b) = 0;
};
// Concrete Class
class MyMath: public ImyMath {
public:
MyMath() {}
int Add(int a, int b);
int Subtract(int a, int b);
int a,b;
};
// Factory function that will return the new object instance. (Only function
// should be declared with DLLCALL)
extern "C" /*Important for avoiding Name decoration*/
{
DLLCALL ImyMath* _cdecl CreateMathObject();
};
// Function Pointer Declaration of CreateMathObject() [Entry Point Function]
typedef ImyMath* (*CREATE_MATH) ();
2. dllSrc.cpp
#include "dllHeader.h"
// Create Object
DLLCALL ImyMath* _cdecl CreateMathObject() {
return new MyMath();
}
int MyMath::Add(int a, int b) {
return a+b;
}
int MyMath::Subtract(int a, int b) {
return a-b;
}
B. Application Project which load and link the already created .dll file:
#include <iostream>
#include <windows.h>
#include "dllHeader.h"
int main()
{
HINSTANCE hDLL = LoadLibrary(L"MyDLL.dll"); // L".\Debug\MyDLL.dll"
if (hDLL == NULL) {
std::cout << "Failed to load library.\n";
}
else {
CREATE_MATH pEntryFunction = (CREATE_MATH)GetProcAddress(hDLL,"CreateMathObject");
ImyMath* pMath = pEntryFunction();
if (pMath) {
std::cout << "10+10=" << pMath->Add(10, 10) << std::endl;
std::cout << "50-10=" << pMath->Subtract(50, 10) << std::endl;
}
FreeLibrary(hDLL);
}
std::cin.get();
return 0;
}
I use some macros to mark the code for import or export
#ifdef ISDLL
#define DLL __declspec(dllexport)
#endif
#ifdef USEDLL
#define DLL __declspec(dllimport)
#endif
Then declare the class in a header file:
class DLL MyClassToExport { ... }
Then #define ISDLL in the libary, and USEDLL before including the header file in the place you want to use the class.
I don't know if you might need to do anything differently for working with LoadLibrary
Recently I asked myself exactly the same question, and summarized my findings in a blog post. You may find it useful.
It covers exporting C++ classes from a DLL, as well as loading them dynamically with LoadLibrary, and discusses some of the issues around that, such as memory management, name mangling and calling conventions.
If you're willing to put a vtable in the class you're exporting, you can export a function that returns an interface and implement the class in the .dll, then put that in the .def file. You might have to do some declaration trickery, but it shouldn't be too hard.
Just like COM. :)

Linker error trying to call extern "C" function from dll

I'm trying to use a C++ class from a native .dll project in a C++/CLI .dll project. Visual Studio 2010, .NET Framework 3.5. So far this is what I have:
// This is a common macro:
#ifdef ISDLL
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
NativeProject:
//INativeType.h:
class DLL INativeType {
public:
virtual void Foo() = 0;
};
//NativeType.h:
class DLL NativeType : public INativeType {
public:
virtual void Foo();
};
extern "C" DLL INativeType CreateNativeType();
//NativeType.cpp:
void NativeType::Foo() {}
extern "C" DLL INativeType* CreateNativeType() {
return new NativeType();
}
C++/CLI Project:
// Wrapper.h:
#include "INativeType.h"
ref class Wrapper {
INativeType* m_nativeType;
};
// Wrapper.cpp:
#include "Wrapper.h"
#include "NativeType.h"
// in some method:
m_nativeType = CreateNativeType();
This gives me the following linker error:
error LNK2028: unresolved token (...) "extern "C" class INativeType * __stdcall CreateNativeType(void)"" ... in Wrapper.obj
Also, although the functions are correctly exported in NativeProject.dll, as I verified it with DependencyWalker, the linker also gives this warning:
warning LNK4199: /DELAYLOAD:NativeProject.dll ignored; no imports found from NativeProject.dll
The C++/CLI project is configured to delay load NativeProject.dll and also includes NativeProject.lib in its linker options. At this point I don't know how to diagnose this linker error. What am I doing wrong?
Why don't you just let the C++/CLI project instantiate the class directly instead of with a factory method?
Besides that, it just looks like you are re-inventing COM (using objects through interfaces). I would just instantiate full-blown C++ classes or, if you really need it, use full-blown COM.
EDIT: Make sure the factory method's calling convention is the same in both the client and the DLL.

Exporting a C++ class from a DLL

Most of my C/C++ development involves monolithic module files and absolutely no classes whatsoever, so usually when I need to make a DLL with accessible functions I just export them using the standard __declspec(dllexport) directive. Then access them either dynamically via LoadLibrary() or at compile time with a header and lib file.
How do you do this when you want to export an entire class (and all it's public methods and properties)?
Is it possible to dynamically load that class at runtime and if so, how?
How would you do it with a header and lib for compile time linking?
What about late-binding? As in loading
it with LoadLibrary() and
GetProcAddress() ? I'm used being able
to load the library at run time and it
would be great if you could do that
here.
So there are two ways to load the DLL. The first is to reference one or more symbols from the DLL (your classname, for example), supply an appropriate import .LIB and let the linker figure everything out.
The second is to explicitly load the DLL via LoadLibrary.
Either approach works fine for C-level function exports. You can either let the linker handle it or call GetProcAddress as you noted.
But when it comes to exported classes, typically only the first approach is used, i.e., implicitly link to the DLL. In this case the DLL is loaded at application start time, and the application fails to load if the DLL can't be found.
If you want to link to a class defined in a DLL, and you want that DLL to be loaded dynamically, sometime after program initiation, you have two options:
Create objects of the class using a special factory function, which internally will have to use (a tiny bit of) assembler to "hook up" newly created objects to their appropriate offsets. This has to be done at run-time AFTER the DLL has been loaded, obviously. A good explanation of this approach can be found here.
Use a delay-load DLL.
All things considered... probably better to just go with implicit linking, in which case you definitely want to use the preprocessor technique shown above. In fact, if you create a new DLL in Visual Studio and choose the "export symbols" option these macros will be created for you.
Good luck...
When you build the DLL and the module that will use the DLL, have some kind of #define that you can use to distinguish between one and the other, then you can do something like this in your class header file:
#if defined( BUILD_DLL )
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif
class IMPORT_EXPORT MyClass {
...
};
Edit: crashmstr beat me to it!
Adding a simple working example for exporting a C++ class from a DLL :
The given below example gives you only a short overview of how dll and exe can interact each other (self explanatory ) but it needs more things to add for changing into a production code.
Full sample example is divided in to two part
A. Creating a .dll library (MyDLL.dll)
B. Creating an Application which uses .dll library (Application).
A. .dll project file (MyDLL.dll):
1. dllHeader.h
#ifdef MYDLL_EXPORTS
#define DLLCALL __declspec(dllexport) /* Should be enabled before compiling
.dll project for creating .dll*/
#else
#define DLLCALL __declspec(dllimport) /* Should be enabled in Application side
for using already created .dll*/
#endif
// Interface Class
class ImyMath {
public:
virtual ~ImyMath() {;}
virtual int Add(int a, int b) = 0;
virtual int Subtract(int a, int b) = 0;
};
// Concrete Class
class MyMath: public ImyMath {
public:
MyMath() {}
int Add(int a, int b);
int Subtract(int a, int b);
int a,b;
};
// Factory function that will return the new object instance. (Only function
// should be declared with DLLCALL)
extern "C" /*Important for avoiding Name decoration*/
{
DLLCALL ImyMath* _cdecl CreateMathObject();
};
// Function Pointer Declaration of CreateMathObject() [Entry Point Function]
typedef ImyMath* (*CREATE_MATH) ();
2. dllSrc.cpp
#include "dllHeader.h"
// Create Object
DLLCALL ImyMath* _cdecl CreateMathObject() {
return new MyMath();
}
int MyMath::Add(int a, int b) {
return a+b;
}
int MyMath::Subtract(int a, int b) {
return a-b;
}
B. Application Project which load and link the already created .dll file:
#include <iostream>
#include <windows.h>
#include "dllHeader.h"
int main()
{
HINSTANCE hDLL = LoadLibrary(L"MyDLL.dll"); // L".\Debug\MyDLL.dll"
if (hDLL == NULL) {
std::cout << "Failed to load library.\n";
}
else {
CREATE_MATH pEntryFunction = (CREATE_MATH)GetProcAddress(hDLL,"CreateMathObject");
ImyMath* pMath = pEntryFunction();
if (pMath) {
std::cout << "10+10=" << pMath->Add(10, 10) << std::endl;
std::cout << "50-10=" << pMath->Subtract(50, 10) << std::endl;
}
FreeLibrary(hDLL);
}
std::cin.get();
return 0;
}
I use some macros to mark the code for import or export
#ifdef ISDLL
#define DLL __declspec(dllexport)
#endif
#ifdef USEDLL
#define DLL __declspec(dllimport)
#endif
Then declare the class in a header file:
class DLL MyClassToExport { ... }
Then #define ISDLL in the libary, and USEDLL before including the header file in the place you want to use the class.
I don't know if you might need to do anything differently for working with LoadLibrary
Recently I asked myself exactly the same question, and summarized my findings in a blog post. You may find it useful.
It covers exporting C++ classes from a DLL, as well as loading them dynamically with LoadLibrary, and discusses some of the issues around that, such as memory management, name mangling and calling conventions.
If you're willing to put a vtable in the class you're exporting, you can export a function that returns an interface and implement the class in the .dll, then put that in the .def file. You might have to do some declaration trickery, but it shouldn't be too hard.
Just like COM. :)