Dll access by excel from c++ code - c++

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.

Related

how we can convert a project written en c++ to dll file?

I have a project written en c++ in which i use tesseract and opencv libraries.
the project contain one function which return an Int ant it has as parameter sting an int
int image_blanche(string nom_img,double k);
My question how can i convert it to dll file to use it in an other .net project
Add a header file (e.g. "Defines.h") containing:
#pragma once
#ifdef COREDLL_EXPORTS
#define COREDLL_API __declspec(dllexport)
#else
#define COREDLL_API __declspec(dllimport)
#endif
Your function should then be defined in a header like this:
#include "Defines.h"
extern "C"
{
COREDLL_API int image_blanche(char const* nom_img,double k);
};
...and implemented in a source file.
Compile that Project with COREDLL_EXPORTS defined as a DLL Project and use the dll in another project.
When building the DLL having COREDLL_EXPORTS defined you basically produce (=export) the symbols and place them in the DLL. When using the DLL in another project not having COREDLL_EXPORTS defined, you consuming/reading (=import) the symbols from the DLL.
Here is a good explanation of how you can then invoke the function from the DLL: Dynamic Invoke C++ DLL function in C#
Update: As MSalters correctly pointed out, using C-Style datatypes should be considered, as it plays friendly across DLL bounds. I changed the string parameter to use a character array instead.

Create a .dll file

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 ...
};

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

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

How to write modules on Windows?

I'm currently writing a program that should be working on both Windows and Linux. The program uses dynamic modules (LoadLibrary/dlopen) to simplify deployment of different functions.
The Linux part works just fine: The main program exports functions and variables with -Wl,--export-dynamic so the modules can access them, and the modules can be compiled with gcc's -shared option without the requirement to resolve all symbol dependencies when linking.
With Windows (using MSVC 2010), this seems not to work. I'm exporting functions and variables from the main program using __declspec(dllimport), but I am not able to access functions and variables from the main program because linking fails (unresolved external, LNK1120).
How to deal with this? Thank you.
Edit (code sample):
core-file.cpp
#include "core-file.hpp"
Cls_A cls_instance;
void Cls_A::do_something() {
while(0);
}
core-file.hpp
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
class TEST_API Cls_A {
public:
void do_something();
};
extern Cls_A cls_instance;
module.cpp
#include "core-file.hpp"
TEST_API int my_init_function() {
cls_instance.do_something();
return 0;
}
__declspec(dllimport) is for when you're compiling the the program that uses the DLL. When you compiling the actual DLL, you want to use __declspec(dllexport).
Your use of these must be consistent. The typical idiom is to define a macro that will use dllimport and dllexport based on the presence of a macro. In the project the builds the DLL, you define the macro that means to export the functions, and in other projects you don't define it, which means to import them:
#ifdef PROJECT_NAME_BUILD_DLL
#define DLL_SYMBOL __declspec(dllexport)
#else //PROJECT_NAME_BUILD_DLL
#define DLL_SYMBOL __declspec(dllimport)
#endif //PROJECT_NAME_BUILD_DLL
DLL_SYMBOL void SomeFunction(Type value);
The project that builds the DLL will define PROJECT_NAME_BUILD_DLL; projects that use the DLL which include this header do not define this.
On Windows, when you want to link against exported symbols you have to remember to specify all the import libraries that were generated when you linked the modules whose symbols you want to import. (You can just leave the symbols unresolved on Linux because the executable format is different and it's possible to defer symbol resolution to load time.)

Exporting static data in a DLL

I have a DLL which contains a class with static members. I use __declspec(dllexport) in order to make use of this class's methods. But when I link it to another project and try to compile it, I get "unresolved external symbol" errors for the static data.
e.g.
In DLL, Test.h
class __declspec(dllexport) Test{
protected:
static int d;
public:
static void m(){int x = a;}
}
In DLL, Test.cpp
#include "Test.h"
int Test::d;
In the application which uses Test, I call m().
I also tried using __declspec(dllexport) for each method separately but I still get the same link errors for the static members.
If I check the DLL (the .lib) using dumpbin, I could see that the symbols have been exported.
For instance, the app gives the following error at link time:
1>Main.obj : error LNK2001: unresolved external symbol "protected: static int CalcEngine::i_MatrixRow" (?i_MatrixRow#CalcEngine##1HA)
But the dumpbin of the .lib contains:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 4BA3611A Fri Mar 19 17:03:46 2010
SizeOfData : 0000002C
DLL name : CalcEngine.dll
Symbol name : ?i_MatrixRow#CalcEngine##1HA (protected: static int CalcEngine::i_MatrixRow)
Type : data
Name type : name
Hint : 31
Name : ?i_MatrixRow#CalcEngine##1HA
I can't figure out how to solve this. What am I doing wrong? How can I get over these errors?
P.S. The code was originally developed for Linux and the .so/binary combination works without a problem
EDIT: In the given case, the static variables are not directly referred by the application but the method is inlined since it's in the header. I was able to resolve the link errors by moving the methods to the .cpp file.
In this thread at cprogramming.com it is suggested that a static variable is local to the dll and not exported.
Summary of discussion below
The static member is not accessed directly by code in the calling application, only through member functions of the class in the dll. However there are several inline functions accessing the static member. Those functions will be inline expanded into the calling applications code makeing the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.
My guess is that the class which uses the DLL should see dllimport instead of dllexport in the header. If I am correct, this can typically be achieved by defining a preprocessor macro like:
#ifdef EXPORTING
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif
and then use it in the class declaration:
class DECLSPEC Test{
protected:
static int d;
public:
static void m(){}
}
So that in Test.cpp (or wherever it makes sense in your DLL project) you can specify that you are exporting so that it will be exported with dllexport:
#define EXPORTING
#include "Test.h"
int Test::d;
while the other project, which does not define EXPORTING, will see dllimport.
Does it make sense?
With Windows DLLs, there is a specific distinction between __declspec(dllexport) vs __declspec(dllimport), dllexport should be used when compiling the DLL, dllimport should be used when compiling programs that link to this DLL. The standard way of defining this would be with a macro.
The following is the visual studio example:
// 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 DLL_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
// DLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
Despite the summary, one can export static data from a DLL. However, there is a problem that comes up with the standard macros supplied by the Visual Studio DLL project:
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
If you have multiple DLLs calling code from one DLL to another or between EXE and DLL, there is going to be a problem with this macro because every header is going to be exporting. One needs unique macros that handle __declspec. The safest way to handle this problem is as follows:
#ifdef MYPROJECT_DLL_EXPORTS
#define MYPROJECT_API __declspec(dllexport)
#else
#define MYPROJECT_API __declspec(dllimport)
#endif
Then only in the compiler preprocessor options for the DLL project define MYPROJECT_API.
In your header code:
struct/class MYPROJECT_API myclass {
static int counter;
};
And in a .cpp file:
int myclass::counter = 0;
Although it's kinda an old post. I would like to add that (for some reason) to resolve this problem I needed to add the (Windows) __declspec(dllexport)/(import) also INSIDE the .cpp file so the outside code could access it.
// From another answer to ilustrate this =)
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
some_app.h
class DLL_API SomeApp
{
static void MyFunc();
}
some_app.cpp
DLL_API void SomeApp::MyFunc()
{
// Some impl of my app.
}
In my case that was specially required because my functions are templated. Maybe this could work for someone else too.
use inline for c++17
static inline std::string static_variable