error C2375: redefinition; different linkage
Asked Answered
Z

6

10

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"

Zap answered 9/9, 2010 at 13:47 Comment(5)
Are you sure that you need to make a non-static member function extern "C" ?Kuching
yes, I need to make .dll to my Python aplicationZap
Maybe you should use a static method? Otherwise, you have an implicit this pointer that you need to take care of. Since you are not exporting the whole class, I am not sure it would work.Kotta
You are going to have to consider how an instance of this class gets created in the first place. Not exporting the constructor is a problem. Not that external code would know how to use it. You'll need to export a factory function.Lobster
Now I've got fatal error LNK1104: cannot open file 'LIBC.lib' - damn ;/Zap
K
6

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

Kotta answered 9/9, 2010 at 13:54 Comment(2)
Can someone correct the macro in this case? I think I have the intent right. Maybe the extern "C" cannot be used on member methods?Kotta
If any declartion specifier preceeds the declaration, it must also preceed the definition in .h file (e.g. __declspec( dllexport ))Winnifredwinning
R
3

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.

Rakel answered 9/9, 2010 at 13:55 Comment(0)
B
3

This may happen because

  1. You defined the prototype of a function in different places with different visibility (extern vs static)
  2. Same as above but different name mangling (extern "C" vs extern "C++")
  3. 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.

Blindheim answered 17/3, 2015 at 18:11 Comment(0)
P
1

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.

Partizan answered 9/9, 2010 at 14:6 Comment(0)
D
0
//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.

Disharoon answered 14/4, 2017 at 21:28 Comment(0)
M
0

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.

Mulder answered 5/4, 2020 at 9:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.