Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a DLL in C and link it from a C++ project

Tags:

c++

c

dll

linker

As per title, I'm trying to build a DLL using C and link it from a C++ project. I read and followed different tutorials on internet but everytime there is something missing and I don't understand what.

Here's what I did, step by step:

I created a new Win32 project, named testlib, then, from the wizard, I chose "DLL" and "Empty project".

Added a header:

//testlib.h

#include <stdio.h>

__declspec(dllexport) void hello();

Added a source; since I want it to be a C source I read I should simplly rename the .cpp file in .c, so

//testlib.c

#include "testlib.h"

void hello() {
    printf("DLL hello() called\n");
}

Build succeded.

Now I would like to use my useful dll in another project.

Then: new project (testlibUse). This time I selected "Empty project".
No need to add an header, just created a cpp source

//main.cpp
#include <testlib.h>

int main() {
    hello();
}

Then:

  • I added the path to the folder where is testlib.dll in Properties->VC++ directories->Executable directories

  • I added the path to the folder where is testlib.h in Properties->VC++ directories->Include directories

  • I added the path to testlib.lib (included extension) in Properties->Linker->Input->Additional dependencies

I tried to build but I got a linker error:

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" (?hello@@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

If I go back to testlib, rename back testlib.c in testlib.cpp and rebuild the dll, then I am able to build testlibUse but I get a "dll not found" error at runtime.

I tried also to change the configurations of both projects in "Release" (changing the path where needed), but nothing changed.

Sorry for the long post but I think it was necessary to write down exactly what I did.

Any suggestions?

Besides, are there any configuration parameters I need to change if I want to use my dll in a Qt project?

like image 251
Manlio Avatar asked May 02 '12 17:05

Manlio


People also ask

How do I add a project to a DLL?

On the menu bar, choose File > New > Project to open the New Project dialog box. In the left pane of the New Project dialog box, select Installed > Visual C++ > Windows Desktop. In the center pane, select Dynamic-Link Library (DLL). Enter MathLibrary in the Name box to specify a name for the project.


2 Answers

You have several problems:

  1. The header file should mark the functions as exported when being compiled in the DLL but imported when being compiled by a library user.
  2. The header file should wrap the function declarations in an extern "C" block when being compiled as C++ to ensure that the names do not get mangled
  3. The DLL is not on your executable's library search path, so it can't be found at runtime.

To fix (1) and (2), rewrite your header like this:

#ifdef __cplusplus
extern "C" {
#endif

// Assume this symbol is only defined by your DLL project, so we can either
// export or import the symbols as appropriate
#if COMPILING_MY_TEST_DLL
#define TESTLIB_EXPORT __declspec(dllexport)
#else
#define TESTLIB_EXPORT __declspec(dllimport)
#endif

TESTLIB_EXPORT void hello();
// ... more function declarations, marked with TESTLIB_EXPORT

#ifdef __cplusplus
}
#endif

To fix (3), copy the DLL into the same folder as your executable file. The "executable directories" setting you're setting doesn't affect DLL searching -- see MSDN for a detailed description of how DLLs are searched for. The best solution for you is to copy your DLL into the directory where your executable file lives. You can either do this manually, or add a post-build step to your project that does this for you.

like image 102
Adam Rosenfield Avatar answered Sep 21 '22 14:09

Adam Rosenfield


You should extern "C" the include:

extern "C" {
    #include <testlib.h>
}
like image 36
MByD Avatar answered Sep 21 '22 14:09

MByD