error C2375: redefinition; different linkage - c++

Error place in api:
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT int CAnyseeUSBTVControllerDlg::InitCaptureDevice()
{
In my .h library class and function definition:
class CAnyseeUSBTVControllerDlg : public CDialog
{
// Construction
public:
int InitCaptureDevice(void);
Any idea how to resolve it?
"Error 1 error C2375:
'CAnyseeUSBTVControllerDlg::InitCaptureDevice'
: redefinition; different
linkage c:\Program
Files\toATS_DVS\anysee\anyseee30\anyseee30\anyseeUSBTVControllerDlg.cpp 122 anyseee30"

You have to make sure you use the same declaration in your header file. Otherwise it is seen as different methods.
class CAnyseeUSBTVControllerDlg : public CDialog
{
// Construction
public:
int InitCaptureDevice(void);
DLLEXPORT int CaptureDevice(void);
See Using dllimport and dllexport in C++ Classes

This may happen because
You defined the prototype of a function in different places with
different visibility (extern vs static)
Same as above but
different name mangling (extern "C" vs extern "C++")
Same as above but different dll export (__declspec(dllimport) vs
__declspec(dllexport)).
To solve, enable /p for files to see how they are preprocessed (this has to be in a file by file basis, and will stop generating .obj for that file), look for a .i file with the result.
Or using /displayincludes, or simply greping thru the code.

You can have DLLEXPORT stated in .cpp file, but not in a header file (because otherwise compiler treats these functions as different ones).
Make your definition also DLLEXPORT.

From http://tldp.org/HOWTO/C++-dlopen/thesolution.html
C++ has a special keyword to declare a
function with C bindings: extern "C".
A function declared as extern "C" uses
the function name as symbol name, just
as a C function. For that reason, only
non-member functions can be declared
as extern "C", and they cannot be
overloaded.
I believe static members may also be possible to extern "C", but you can't do what you're trying to do directly. You'll need to make a C-only wrapper interface that calls your class member functions. You can then extern "C" the wrappers and expose that outside your DLL.

//foo.h
#pragma once
#ifdef FOO_EXPORTS
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif
namespace foo
{
class Baz
{
public:
FOO_API static auto say_hello() -> void;
};
}
The key things, not so much the function names, or my use of the trailing return type, is that you put the name of the #defined __declspec in front of the function you want to export, much like you would a type.
You would also do the same in the function definition:
//foo.cpp
#include "foo.h"
namespace foo
{
FOO_API auto Baz::say_hello() -> void
{
do
{
MessageBox(nullptr, L"Seems to be working okay!", L"OK", MB_OK);
exit(1);
}
while (0);
}
}
The function implementation isn't important, just that you put FOO_API in front.

Today I faced the same issue and for me, I had failed to include the type before my class.
That is I had to change :
class Core
{
private:
py::object cls;
py::object obj;
py::object startFunc;
py::object startFuncAsync;
py::object stopFunc;
...
public:
...
};
to
#ifndef CORE_H
#define CORE_H
/* If we are we on Windows, we want a single define for it.*/
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
#define _WIN32
#endif /* _WIN32 */
#if defined(_WIN32) && defined(_CORE_BUILD_DLL)
/* We are building FV as a Win32 DLL */
#define CORE_API __declspec(dllexport)
#elif defined(_WIN32) && defined(CORE_DLL)
/* We are calling FV as a Win32 DLL */
#define CORE_API __declspec(dllimport)
#elif defined(__GNUC__) && defined(_CORE_BUILD_DLL)
/* We are building FV as a shared / dynamic library */
#define CORE_API __attribute__((visibility("default")))
#else
/* We are building or calling CORE as a static library */
#define CORE_API
#endif
class CORE_API Core
{
private:
py::object cls;
py::object obj;
py::object startFunc;
py::object startFuncAsync;
py::object stopFunc;
...
public:
...
};
Side note:
This will allow for building your project as a dll or a lib and neither of them (i.e. use them by including them) and you can also compile this code under linux, so nothing platform specific here.
If you are in visual studio and want to build a dll, just go to Properties>C/C++>CommandLine and enter :
/D_CORE_BUILD_DLL
and replace CORE with your own designated name.

Related

C++ Visual Studio Windows: how to declare but not define extern function in dll

I have a project that is compiled into a library and declares a certain function to be implemented by the user of the library:
//To be defined by user
Application* CreateApplication();
When compiling the code into a shared library on Linux this works perfectly. Any user of the library can define an implementation for the declared function and it can be used inside the library. If the user of the library forgets to define an implementation, they will get an error pointing this out.
I'm now in the process of porting the library to Windows, where it is supposed to be compiled into a dll. However, I'm running into problems as the linker used by Visual Studio is complaining:
unresolved external symbol Application* __cdecl CreateApplication(void)
I tried adding the extern keyword to indicate that the definition of the function is somewhere else, but this didn't work.
Why can't I declare (but not define) a function in a dll like this? How should I fix my code so it works both on Linux and on Windows?
What you are attempting to do only works in a static library, it cannot work in a dynamic library like a DLL. For that, you will have to change the code to use a function pointer instead. The application that is using the DLL can pass in the address of the desired function from its own code, and the DLL can then assign that address to a variable that it uses as needed, eg:
HEADER:
#ifndef MYLIB_H
#ifndef MYLIB_H
#ifdef COMPILING_MY_LIB
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
// declare Application as needed...
typedef Application (*lpCreateApplicationFunc)();
#ifdef __cplusplus
extern "C" {
#endif
MY_EXPORT void SetCreateApplicationFunc(lpCreateApplicationFunc func);
#ifdef __cplusplus
}
#endif
#endif
DLL:
#define COMPILING_MY_LIB
#include "MyLib.h"
//To be defined by user
lpCreateApplicationFunc CreateApplication = NULL;
void SetCreateApplicationFunc(lpCreateApplicationFunc func)
{
CreateApplication = func;
}
void doSomething()
{
Application *app = NULL;
if (CreateApplication)
app = (*CreateApplication)();
if (app)
{
...
}
}
EXE:
#include "MyLib.h"
Application MyCreateApplicationFunc()
{
...
}
// during startup, call this...
SetCreateApplicationFunc(&MyCreateApplicationFunc);

How to properly create a DLL from C code and use it in a C++ project

I have a set of functions written in C that I need to be able to call from another project written in C++. The C code is essentially some functions that do some calculations on a large data set. I didn't write them - all I want to do is allow my C++ project to be able to call those functions. My solution was to create a DLL for the C code and link it to my C++ project.
In order to make the DLL, I structured myCproj.h (the header in the C project, not C++ project) like so:
#ifdef __cplusplus
extern "C" {
#endif
struct __declspec(dllexport) neededStruct {
int a;
//I need to be able to initialize this struct in my C++ project.
}
__declspec(dllexport) void neededFunc( struct neededStruct *input ) {}
//I need to be able to call this function from my C++ project and feed
//it my local instance of neededStruct.
#ifdef __cplusplus
}
#endif
The src file, myCproj.c, was not changed at all. The function definitions do not have __declspec(dllexport)in front of them, nor is extern "C" inserted anywhere. The code compiles without error and produces myCproj.dll and myCproj.lib.
I then tell my C++ project in VS where to find myCproj.lib and myCproj.h accordingly and copy the DLL over to the directory where my C++ executable lives. To use the DLL, I gave myCPPproj.cpp the following addition:
#define DLLImport __declspec(dllimport)
struct DLLImport neededStruct input;
input.a = 0;
extern "C" DLLImport void neededFunc( &input );
However, I get error EO335 'linkage specification is not allowed' on that last line. What am I doing wrong?
It is preferable to use the same header for both the library and using code.
As mentioned, it is usually done by a conditional define, like the following:
MyLibrary.h:
#if defined(MYLIBRARY_API)
#define MYLIBRARY_EXPORTS __declspec(dllexport)
#else
#define MYLIBRARY_EXPORTS __declspec(dllimport)
#endif
#if defined(__cplusplus)
extern "C" {
#endif
MYLIBRARY_API bool MyLibFunc();
#if defined(__cplusplus)
#endif
MyLibrary.c:
#include "MyLibrary.h"
void MyLibFunc()
{
....
}
App.cpp:
#include <MyLibrary.h>
int main()
{
MyLibFunc();
}
The symbol MYLIBRARY_API will be defined for the library project (usually as a /D on the compiler command line). And if you use visual studio that is pretty much exactly what you get when creating a dll project with exports.

Defining a struct imported from DLL works only when its constructor is defined in the header file [duplicate]

This question already has answers here:
How do I safely pass objects, especially STL objects, to and from a DLL?
(4 answers)
Closed 7 years ago.
I have a class which has two overloaded functions. How do I export it from a dll and also how to use it by other C++ classes? My class looks like this:
#define DECLDIREXP __declspec(dllexport)
#define DECLDIRIMP __declspec(dllimport)
class DECLDIREXP xyz
{
public:
void printing();
void printing(int a);
};
using namespace std;
void xyz::printing()
{
cout<<"hello i donot take any argument";
}
void xyz::printing(int a)
{
cout<<"hello i take "<< a <<"as argument";
}
A common approach is to have a single macro (let's call it EXPORT) which either expands to dllimport or dllexport depending on whether some sort of "building the DLL right now" define is set, like this:
#ifdef MAKEDLL
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
class EXPORT xyz {
// ...
};
The idea is that when building your DLL, you add MAKEDLL to the preprocessor definitions. That way, all the code will be exported. Clients who link against your DLL (and hence include this header file) don't need to do anything at all. By not defining MAKEDLL, they will automatically import all the code.
The advantage of this approach is that the burden of getting the macros right is moved from the many (the clients) to just the author of the DLL.
The disadvantage of this is that when using the code above as it is, it's no longer possible to just compile the code directly into some client module since it's not possible to define the EXPORT macro to nothing. To achieve that, you'd need to have another check which, if true, defines EXPORT to nothing.
On a slightly different topic: in many cases, it's not possible (or desired!) to export a complete class like that. Instead, you may want to just export the symbols you need. For instance, in your case, you may want to just export the two public methods. That way, all the private/protected members won't be exported:
class xyz
{
public:
EXPORT void printing();
EXPORT void printing(int a);
};
As I remember, normally, you export not a class but a factory function that creates a new instance of class and returns a pointer. The class declaration resides in header file for compile time.
I may be wrong about the example (that was long ago), but here how it should approximately look like:
Header file (.h):
class MyClass { ... };
extern "C" DLL_API MyClass* createMyClass();
Source file (.cpp):
DLL_API MyClass* createMyClass() {
return new MyClass();
}
Define MY_DLL_EXPORT while compiling, see foraidt's answer example.
One another option:
Use the default defined macro local to the project.
You can see the default defined macros local to the project in the below location:
Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.
Example:
Suppose your Project Name is: MyDLL
Default Macro Local to that project: MYDLL_EXPORTS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT Class_Name {
//....
}
When compiling your library you should define a macro (command line preprocessor definition), let's call it MY_DLL_EXPORT.
Then in your library's code do something like this:
#ifdef MY_DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
class DLL_API some_class { /*...*/ }

No functions get exported into DLL despite proper dllExport - Visual Studio

I have a base class (QIndicator) and I want to implement derived classes in DLLs. The DLL project in Visual Studio 2012 for a sample derived class has the following code:
header file with base class
#ifndef _DLL_COMMON_INDICATOR_
#define _DLL_COMMON_INDICATOR_
// define the DLL storage specifier macro
#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
class QIndicator
{
private:
int x;
int y;
};
extern "C"
{
// declare the factory function for exporting a pointer to QIndicator
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
#endif
source file with derived class
#define DLL_EXPORT
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
public:
QIndicatorDer (void) : QIndicator(){};
~QIndicatorDer (void){};
private:
// list of QIndicatorDer parameters
int x2;
int y2;
};
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
The problem I have is that upon successful build, the produced DLL file does not contain the exported getIndicatorPtr function (as shown by DependencyWalker). I checked whether the dllexport keyword gets propagated properly into the declaration of getIndicatorPtr and it does.
Another interesting problem is that I already have another derived class like this, in another DLL project, that I created some months ago. This older project is basically the same and everything works well there. I checked all properties of both the old and the current projects, and they seem identical. So I ran out of ideas, why I can't get getIndicatorPtr to export.
Any help is much appreciated,
Daniel
That's because it's not being exported. Why?
__declspec specifier should only be placed in the declaration of a function, not it's definition. Also, avoid something like #define DLL_EXPORT. Preprocessor definitions should either defined in project properties (MSVC) or command line option (-D in GCC, for example).
Look at you code:
Header
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
When compiler parses this header, is sees DECLDIR as dllimport (because you define DLL_EXPORT in .cpp). Then in .cpp, it suddenly appears as dllexport. Which one is used? The first one.
So, leave your header (it's fine), but change your source:
//#define DLL_EXPORT -> remove this!
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
//...
};
extern "C"
{
/* DECLDIR -> and this! */ QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
Then, go to project properties (I assume you use Visual Studio) and then C/C++ -> Preprocessor -> Preprocessor Definitions and add there DLL_EXPORT=1.
That should work.

Why does linker fail when accessing static member in inline constructor

Just started doing some coding for a very simple automated test framework for internal use. (I know there are hundreds of them out there - really good ones too, but at the moment that's not interesting, so don't point me to any of those, please ;)) I then came across the following problem which I can't explain, thus asking for your help.
I have the following code as part of a DLL:
(The code is barely an embryo and took me <2 minutes to write, so it's logic, structure - nothing - is refined, in any way yet.)
h-file:
#pragma once
#ifdef __DLL__ // Defined in DLL-project
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT
#endif
class DLLEXPORT AutoTest
{
public:
enum eTestID {TESTID_SomeFunction};
AutoTest(eTestID id, LPVOID lpData)
{
if(sm_bTestsActive)
ExecTest(id, lpData);
}
void ActivateTests();
private:
static void ExecTest(eTestID id, LPVOID lpData)
{
}
static BOOL sm_bTestsActive;
};
cpp-file:
#include "StdAfx.h"
#include "AutoTest.hpp"
BOOL AutoTest::sm_bTestsActive = FALSE;
void AutoTest::ActivateTests()
{
sm_bTestsActive=TRUE;
}
This compiles just fine and the DLL gets generated.
Here's my problem though - when instantiating the class with:
AutoTest(AutoTest::TESTID_SomeFunction, &SomeData);
from the main application, the linker fails with
error LNK2001: unresolved external symbol "private: static int AutoTest::sm_bTestsActive" (?sm_bTestsActive#AutoTest##0HA)
<2 minutes to write - now going on 5 hours to understand why it fails!!! :O
Here's what interesting - if I move the constructor to the cpp-file (not inlined) it works just fine!?!?
Here's that code:
h-file:
#pragma once
#ifdef __DLL__ // Defined in DLL-project
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT
#endif
class DLLEXPORT AutoTest
{
public:
enum eTestID {FK3059};
AutoTest(eTestID id, LPVOID lpData);
void ActivateTests();
private:
static void ExecTest(eTestID id, LPVOID lpData)
{
}
static BOOL sm_bTestsActive;
};
cpp-file:
#include "StdAfx.h"
#include "AutoTest.hpp"
BOOL AutoTest::sm_bTestsActive = FALSE;
AutoTest::AutoTest(eTestID id, LPVOID lpData)
{
if(sm_bTestsActive)
ExecTest(id, lpData);
}
void AutoTest::ActivateTests()
{
sm_bTestsActive=TRUE;
}
(I've made some minor edits in the code after pasting, so there may or may not be simple syntax errors.)
Also, if I remove the reference to the static member from the inline versions constructor, it works fine.
Any ideas as to why the inline version won't work?
Pay attention to your definition of DLLEXPORT.
Make sure that it is properly expanded to __declspec(dllexport) when building the DLL, or __declspec(dllimport) when building the client.
I'd suggest using a macro with a more specific name than the generic DLLEXPORT (to avoid conflicts with other macros with the same name).
Having static data members accessed from inline member functions works fine for me (tested with VS2013).
Minimal repro:
Create a Visual Studio solution with an empty DLL project and an empty console application project.
Inside the DLL project add two files:
DllClass.h:
#pragma once
#ifndef TEST_DLL_CLASS
#define TEST_DLL_CLASS __declspec(dllimport)
#endif
class TEST_DLL_CLASS DllClass
{
public:
DllClass();
int GetMember() const
{
return m_data1;
}
static int GetStaticMember()
{
return sm_data2;
}
private:
int m_data1;
static int sm_data2;
};
DllClass.cpp:
#define TEST_DLL_CLASS __declspec(dllexport)
#include "DllClass.h"
int DllClass::sm_data2 = 2;
DllClass::DllClass()
: m_data1(1)
{
}
Inside the console app project, add one file:
Test.cpp:
#include "..\DllTestClass\DllClass.h"
#include <iostream>
using namespace std;
#pragma comment(lib, "DllTestClass")
int main()
{
DllClass dllClass;
cout << dllClass.GetMember() << endl;
cout << DllClass::GetStaticMember() << endl;
}
Make sure that when building the console test app, the linker can find the DLL .lib (DllTestClass.lib) file.
For that purpose, you can navigate the console app's project properties, going to:
Project Properties | Linker | Additional Library Directories
and add $(OutDir) to the additional library directories, making it:
$(OutDir);%(AdditionalLibraryDirectories)
Builds and works correctly for me.
Should be:
#ifdef __DLL__ // Defined in DLL-project
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT __declspec( dllimport )
#endif
You can declare C++ classes with the dllimport or dllexport attribute. These forms imply that the entire class is imported or exported. Classes exported this way are called exportable classes.
More information in the documentation.