I have 4 files:
mySender.h mySender.cpp myReceiver.h myReceiver.cpp
I want to import these 4 file in a .dll project "MyIfa" in VisualStudio 2012.
I create a new project--->win32--->I choose export external symbols in the wizard---->at least the project is created (the new folder is created with all the components).
Now what I need to do?
Add the four file (add existing items) in my project and building?
Add the four file (add existing items) in my project, includes the .h
files (mySender.h, myReceiver.h) and building?
Add the four file (add existing items) in my project, includes the .h
files (mySender.h, myReceiver.h) , add additional directories and
libraries (that I use in mySender.h, myReceiver.h,mySender.cpp,
myReceiver.cpp) in the project properties and building?
this is the new code generated:
IfacomAmqDll.h
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the IFACOMAMQDLL_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// IFACOMAMQDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef IFACOMAMQDLL_EXPORTS
#define IFACOMAMQDLL_API __declspec(dllexport)
#else
#define IFACOMAMQDLL_API __declspec(dllimport)
#endif
// This class is exported from the IfacomAmqDll.dll
class IFACOMAMQDLL_API CIfacomAmqDll {
public:
CIfacomAmqDll(void);
// TODO: add your methods here.
};
extern IFACOMAMQDLL_API int nIfacomAmqDll;
IFACOMAMQDLL_API int fnIfacomAmqDll(void);
this is IfacomAmqDll.cpp:
// IfacomAmqDll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "IfacomAmqDll.h"
// This is an example of an exported variable
IFACOMAMQDLL_API int nIfacomAmqDll=0;
// This is an example of an exported function.
IFACOMAMQDLL_API int fnIfacomAmqDll(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see IfacomAmqDll.h for the class definition
CIfacomAmqDll::CIfacomAmqDll()
{
return;
}
So what I need to do with my existing .h and .cpp file to be able to export all the classes that are defined inside?
If you ran the wizard to create a DLL project with some example exports, you can see the format you need to follow to export classes and/or functions from your dll. It should be as simple as this:
Add your existing source files to the DLL project.
For any class you want to export, #include the generated DLL header file and prepend the #define'ed symbol that resolves to __declspec(dllexport) to the class name.
Rebuild.
For example, the wizard will have generated a header file, say header.h that includes something like this:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the WIN32PROJECT2_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// WIN32PROJECT2_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef WIN32PROJECT2_EXPORTS
#define WIN32PROJECT2_API __declspec(dllexport)
#else
#define WIN32PROJECT2_API __declspec(dllimport)
#endif
Now, suppose you have an existing class called CMyClass in your existing source code:
class CMyClass
{
// ... blah ...
};
If you want to export his class from the dll, do this:
#include "header.h"
class WIN32PROJECT2_API CMyClass
{
// ... blah ...
};
Related
I am trying to create a DLL from C++ code using visual studio 2015.
I have a DLL_Tutorial.h file :
#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream>
extern "C"
{
DECLDIR int Add( int a, int b );
}
#endif
\\
\ Then I created a DLL_Tutorial.cpp
#include <iostream>
#include "DLL_Tutorial.h"
#define DLL_EXPORT
extern "C"
{
__declspec(dllexport) int Add(int a, int b)
{
return(a + b);
}
}
I got a Dll file
I would like to call my function in VBA and apply that to an excel sheet
so in VBA I did :
Public Declare Function Add _
Lib "C:\Users\hasna\Desktop\Projet VBA-C++\projet5\Debug\projet5.dll" (byval a As integer,byval b As integer) As integer
Then in an excel sheet, I enter 2 values (for example 6 and 4 ) I call add function but it gave me : #VALEUR!
Where is the problem ?
Could you please help me resolve that
Thanks
In your DLL header file, it does not appear that you've prefixed the exported API with __declspec(dllexport). Which is usually defined so that the API can use __declspec(dllexport) when building the DLL, and __declspec(dllimport), when the header is being used in an external project. The best thing would be to just create the DLL using the VS 2015 project template, it includes the correct headers, and export definitions for you, so you just need to focus on writing the APIs. Here's a working example from a VS 2015 project:
Example *.h:
#pragma once
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the DLLAPI_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// DLLAPI_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DLLAPI_EXPORTS
#define DLLAPI_API __declspec(dllexport)
#else
#define DLLAPI_API __declspec(dllimport)
#endif
// This is an example of an exported function.
DLLAPI_API int fnDLLAPI(void);
Example *.cpp:
// DLLAPI.cpp : Defines the exported functions for the DLL application.
//
#include "DLLAPI.h"
// This is an example of an exported function.
DLLAPI_API int fnDLLAPI(void)
{
return 42;
}
The Windows Via C/C++ book is also a very good resource regarding writing DLLs. Now regarding the VB import, I am not sure as I am not familiar with importing APIs via VB.
I have inherited a Linux project that I need to port to Windows and Visual Studio. I have setup the same project structure as was the case in Linux but I find the structure a bit strange (maybe it is all good in Linux) and I believe that's what's causing the LNK4217 (locally defined symbol 'symbol' imported in function 'function') and C4273 ('function' : inconsistent DLL linkage) warnings I receive. I would like some advice on how to re-structure the project or change the code to avoid these warnings. Basically this is what I have:
Dll project called Foo
Dll project called Bar (depends on the Foo dll)
The part that I find strange and what I believe causes the LINK4217 and C4273 warnings is that both the Foo and Bar library contain the header and source file for the class MyClass (the warnings mention this class):
//MyClass.h
class BAR_API MyClass
{
//Methods etc.
}
Where BAR_API is defined as __declspec(dllexport) in the Bar library while in the Foo library it is __declspec(dllimport) according to:
#ifdef BAR_EXPORTS
#define BAR_API __declspec(dllexport)
#else
#define BAR_API __declspec(dllimport)
#endif
How do you propose I change this? Would it help to move MyClass to its own library and have Foo and Bar include it or change so that BAR_API is defined as nothing instead of __declspec(dllimport) in the Foo library?
Let's see what you have here
1. Foo.dll that defines MyClass and exports it
2. Bar.dll that depends on Foo.dll, but also defines MyClass - and this is the source of ambiguity that confuses your linker.
The right thing, to my understanding, is to:
Define MyClass in Foo.dll (since Bar.dll already depends on it) and export MyClass using __declspec(dllexport) in Foo.dll's MyClass declaration.
#include header file that declares MyClass (where it will be specified as imported using __declspec(dllimport)) where appropriate in the Bar.dll's .cpp files; however, do not include the .cpp file that implements MyClass.
BAR_API (which in this case should be renamed to FOO_API) helps you achieve this by being defined as either dllexport or dllimport based on whether BAR_EXPORTS (which in this case should be renamed to FOO_EXPORTS) is defined. You should #define FOO_EXPORTS in every source file in the Foo project either by setting compiler command line parameter or by #including common header that #defines FOO_EXPORTS in every .cpp file in the Foo project (but not in the Bar project).
This way both Foo.dll and Bar.dll will use MyClass from the Foo.dll.
HTH
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?
You have several problems:
The header file should mark the functions as exported when being compiled in the DLL but imported when being compiled by a library user.
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
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.
You should extern "C" the include:
extern "C" {
#include <testlib.h>
}
It looks as if you need to make sure the compiler not mangle the symbol name in the cpp build. You should be able to add an extern "C" to the definition in testlib.h:
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllexport) void hello();
Here's a method for your C header file that could be included by C++. Make sure to set TESTLIB_EXPORTS only in your DLL preprocessor settings. In projects that include this header to use the DLL, the header will declare the functions as imports instead of exports.
The __cplusplus guard will tell the compiler to import your functions using C name decoration instead of C++ name decoration.
#include <stdio.h>
#ifdef TESTLIB_EXPORTS
#define TESTLIB_API __declspec(dllexport)
#else
#define TESTLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
TESTLIB_API void hello();
/* other prototypes here */
#ifdef __cplusplus
}
#endif
I have a dll with a class that define some methods and variables inside it. I marked it as
__declspec(dllexport)
and i imported the .h header inside a win32 application project in the same solution. I can use the functions but when I try to compile the project I have a lot of errors about external symbols not resolved. Why?
Please read about the standard way of using macros for this very common task here: http://wiki.tcl.tk/8721
The basic idea is that you define a macro, say MY_API like so:
#ifdef BUILD_MYAPI
# define MY_API __declspec(dllexport)
#else
# define MY_API __declspec(dllimport)
#endif
When you declare a function or a class in the header file you do this:
void MY_API myApiFunction(int x);
When you build your own dll which declares the body of the function, you add the definition of BUILD_MYAPI to the build. This makes all declerations to be dllexport
when you include the header from some other dll you don't add BUILD_MYAPI so the decelerations are dllimport
When compiling with visual studio, you can add a macro definition to the compilation without changing the source from project properties -> C/C++ -> Preprocesson -> Preprocessor definitions
For the application where you want to import that class, you will need to mark the class as
__declspec(dllimport)
Instead of dllexport.
You must also make sure to link with the import library of the DLL (a .lib file).
I have a application and several plugins in DLL files. The plugins use symbols from the
application via a export library. The application links in several static libraries and this is where most of the symbols come from. This works fine as long as the application uses a symbol. If the symbol is not used there, I get linker errors when compiling the DLL.
How can I force the export of the symbols only used in the plugins?
In order to trigger the export I've tried something like this:
class MyClassExporter
{
MyClass mInstance;
public:
MyClassExporter() {}
};
static MyClassExporter TheMyClassExporter;
in one of the static libs the application is made of to force the export, which didn't work.
In response to Greg (thanks for the answer) and to clarify: The class I want to force the export for is MyClass (which has __declspec(...) defined, depending on wether I want to export or import). MyClassExport was my attempt to force the inclusion of unused (in terms of the application) symbols into the app. I want to 'touch' the symbols so that the linker recognizes them as used and includes them into the application so that it can in turn export these to my plugins. Linking the static libs into the plugins is not an option, since they contain singletons which would be duplicated (app and DLLs each have their own copy of static variables).
The /INCLUDE directive can be used to force the MSVC linker to include a symbol. Alternatively, /OPT:NOREF can be used to disable removal of unused symbols in general.
A common approach is to create a single unused function that references all objects exported for your plugins. Then you only need a single /INCLUDE directive for that function.
You probably want to look at __declspec(export/import)
#ifdef DLL_EXPORTING
#define WHDLL __declspec(dllexport)
#else
#define WHDLL __declspec(dllimport)
#endif
When linking static module into a dll it will only bring in the code that is used. I've never imported stuff from a static lib to simply re export it.
Perhaps you just need to mark it as exportable in the dll when compiling the static lib.
But that reminds me of putting std containers into exported classes and using some trickery in msvc to export the 'instance' of the specialised container. the template code is similar to your static code (in my thinking)
for instance without the template you get warnings the template code is not exported to support the class - this is MSVC specific from my understanding
template class DLL_EXPORTING std::auto_ptr<wxCursor>;
class DLL_EXPORTING imageButton : public wxWindow
{
std::auto_ptr<wxCursor> m_Cursor;
};
What I tried out to solve this was this:
build a static library with function void afunction( int ).
build a dll, linked to static lib, exporting afunction.
build an exe, using the afunction symbol.
How? Since the linker can be told to export functions using the __declspec(dllexport) directive, a dll needs no more than declare a to-be-exported symbol thusly.
The lib has a header "afunction.h" and an accompanying cpp file containing the function body:
// stat/afunction.h
namespace static_lib { void afunction(int); }
// stat/afunction.cpp
#include "afunction.h"
namespace static_lib { void afunction(int){ } }
The dll has an include file "indirect.h", containing the declaration of the function to be exported. The dll has a link-time dependency to the static lib. (Linker options: Input/Additional Dependencies: "static_library.lib")
// dll/indirect.h
namespace static_lib {
__declspec( dllexport ) void afunction(int);
}
The executable has only the indirectly included file:
#include <dll/indirect.h>
int main() { static_lib::afunction(1); }
And guess what? It compiles, links and even runs!
The "Use Library Dependency Inputs" option does the trick in VS2005!
This option can be found under Configuration Properties -> Linker -> General -> Use Library Dependency Inputs. Set to "true" to force linking in ALL symbols & code declared in every LIB specified as input to the project.
You can do the following to get the symbol to export from the DLL: define LIB_EXPORTS in the library project and nothing in either the DLL project or the DLL client project.
#ifdef LIB_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
Turns out there is no need #include any headers from the LIB project when compiling the DLL project; just specify the LIB as a linker input. However, if you need to make use of the LIB code from within the DLL, you will need to #define DLLAPI as an empty macro; setting the symbol(s) to either dllexport or dllimport will generate an error or a warning, respectively.
There is some discussion of this problem on MSDN which was pretty useful. As it turns out, /OPT:NOREF is not particularly helpful in this case. /INCLUDE can work but it can be hard to automatically figure out what needs to be /INCLUDEd. There's unfortunately no silver bullet.
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/2aa2e1b7-6677-4986-99cc-62f463c94ef3