Error LNK2028 when calling exported C function from C++ wrapper - c++

I have C project from which I export function f() and call it from other C++ project and it works fine. However, when I call some other function g() inside f I get LNK2028 error.
The minimal example of Cproject looks like:
Test.h
#ifndef TEST_H
#define TEST_H
#include "myfunc.h"
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT void f()
{
g(); // this will provide LNK2028 if f() is called from other project
}
#endif
myfunc.h
void g();
myfunc.c
#include "myfunc.h"
void g(){}
The project itself is being built. However, when I call this function from other C++/CLIproject
#include "Test.h"
public ref class CppWrapper
{
public:
CppWrapper(){ f(); } // call external function
};
I get error:
error LNK2028: unresolved token (0A00007C) "void __cdecl g(void)" (?g##$$FYAXXZ) referenced in function "extern "C" void __cdecl f(void)" (?f##$$J0YAXXZ) main.obj CppWrapper
error LNK2019: unresolved external symbol "void __cdecl g(void)" (?g##$$FYAXXZ) referenced in function "extern "C" void __cdecl f(void)" (?f##$$J0YAXXZ) main.obj CppWrapper
Additional details:
I set x64 platform for whole solution
In CppWrapper I include .lib file from C project

Test.h
#ifndef TEST_H
#define TEST_H
#ifdef BUILDING_MY_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
DLL_EXPORT void f();
#ifdef __cplusplus
}
#endif
#endif
Test.c
#include "Test.h"
#include "myfunc.h"
void f()
{
g();
}
In your C project you have to add BUILDING_MY_DLL to
Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions
The only real change is that I added the toggle between __declspec(dllexport) and __declspec(dllimport). Changes required:
Moved f's body to Test.c because functions imported with __declspec(dllimport) cannot have a definition already.
Other changes:
Do never write extern "C" without an #ifdef __cplusplus guard, or many C compilers will not compile your code.

I just spent 2 days fighting this exact same problem. Thank you for the solution. I'd like to extend it.
In my case, I am calling a c function from an exported c++ dll function and I was getting the same error. I was able to fix it so (using your example)
#ifndef TEST_H
#define TEST_H
#ifdef BUILDING_MY_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "myfunc.h"
#ifdef __cplusplus
}
#endif
#endif

Related

Error "linkage specification is not allowed" when using extern "C" with __declspec(dllexport) in a C++ class

When I am using using extern "C" with __declspec(dllexport) in the Class, then I am getting an error "linkage specification is not allowed".
If i declare this outside of the class then i am not getting any error.
Could someone please help me how to use extern "C" with __declspec(dllexport) with in the Class
Below is the code snippet:
#ifdef _WIN32
#define DECLSPEC extern "C" __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif
class MyClass
{
DECLSPEC static std::shared_ptr<ITestInterface> GetInstance();
};

calls to static member variable causes LNK2001 in DLL

Im testing a DLL library I'm writing and after trying to compile it, I get a LNK2001 error for a static variable within a class.
FooApi.h
#ifdef PLATFORM_WINDOWS
#ifdef FOO_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif
#else
#define FOO_API
#endif
Bar.h
class FOO_API Bar
{
private:
static bool mIsActive;
};
and in Bar.cpp:
bool FOO_API Bar::mIsActive = false;
Upon building a test project using the DLL, I get an LNK2001 unresolved external symbol. Any ideas on how to resolve this? Sidenote: none of my static functions within the same class has this issue.
Error:
error LNK2001: unresolved external symbol "public: static bool
vkdebug::Bar::mIsActive" (?mIsActive#Bar#vkdebug#2_NA)

Error: function definition is marked dllimport

I'm attempting to get a toy program running with AVT's VIMBA SDK. At the moment, it is going well save for one caveat. When I attempt to compile, I get a series of errors (14 of them) that all are marked same thing:
function *insert call here* definition is marked dllimport
The file itself is below- the curious thing is that in in this file, only ~IFeatureObserver(), IFeatureObserver(), and IFeatureObserver( const IFeatureObserver& ) are triggering the error; FeatureChanged() does not error out during a compile.
#ifndef AVT_VMBAPI_IFEATUREOBSERVER_H
#define AVT_VMBAPI_IFEATUREOBSERVER_H
#include <VimbaCPP/Include/VimbaCPPCommon.h>
#include <VimbaCPP/Include/SharedPointerDefines.h>
#include <VimbaCPP/Include/Feature.h>
#include <vector>
namespace AVT {
namespace VmbAPI {
class IFeatureObserver
{
public:
IMEXPORT virtual void FeatureChanged( const FeaturePtr &pFeature ) = 0;
IMEXPORT virtual ~IFeatureObserver() {}
protected:
IMEXPORT IFeatureObserver() {}
IMEXPORT IFeatureObserver( const IFeatureObserver& ) { /* No copy ctor */ }
};
typedef std::vector<IFeatureObserverPtr> IFeatureObserverPtrVector;
}} // namespace AVT::VmbAPI
#endif
After tracking down source of IMEXPORT, I found it in a .h file.
#if defined (_WIN32)
#if defined AVT_VMBAPI_CPP_EXPORTS // DLL exports
#define IMEXPORT __declspec(dllexport)
#elif defined AVT_VMBAPI_CPP_LIB // static LIB
#define IMEXPORT
#else // import
#define IMEXPORT __declspec(dllimport)
#endif
#elif defined (__GNUC__) && (__GNUC__ >= 4) && defined (__ELF__)
#define IMEXPORT
#elif defined (__APPLE__)
#define IMEXPORT
#else
#error Unknown platform, file needs adaption
#endif
I am currently programming in Qt on a Win7-32 bit machine, and as far as I can tell IMEXPORT is being defined as __declspec(dllimport).
Thoughts? Thanks in advance!
You should define the macro AVT_VMBAPI_CPP_EXPORTS in your makefile or VS project. This way IMEXPORT is defined as dllexport for this library and dll import when other libraries/app use it.
BTW it's cleaner to add this attribute to the class itself, not every function.
class IMEXPORT IFeatureObserver {
public:
virtual void FeatureChanged( const FeaturePtr &pFeature ) = 0;
};

build(compile.link) application code with only DLL *.h header file and load DLL implementation in run-time (explicit linking)

I have an application code which invokes a DLL lib with explicit linkage (or run time linking) for accessing an exported class.
DLL.h
#ifdef DLL_EXPORT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
FooDLL.h
#include "DLL.h"
class DLL_API Foo
{
public:
void doSomeThing();
};
extern "C" DLL_API Foo* _getInstance() {
return new Foo();
}
typedef Foo* (*getInstanceFactory)();
Foo* getInstance() {
HINSTANCE dllHandle = LoadLibraryA("Foo.dll");
getInstanceFactory factory_func = (getInstanceFactory)GetProcAddress(dllHandle, "_getInstance");
return factory_func();
}
FooDLL.cpp
#include "FooDLL.h"
Foo::doSomething() {
// .......
}
Application.cpp (which invokes DLL)
#include "FooDLL.h"
Foo* obj = getInstance();
obj->doSomething(); // XXX this line can be compiled and linked only when DLL is already in path
The above code can be built (e.g. compiled&linked) only when the DLL file is included in lib path. Otherwise I got unresolved external symbol error.
error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall Foo::doSomething()" .....
Is it possible to build the application code with only DLL header file (i.e. FooDLL.h) and without DLL/LIB files during the build time? (p.s. The class implementation must be in cpp file.)
thanks!
with virtual function.
class Foo
{
public:
void virtual doSomeThing();
};
Yes it is possible. If you did not export a class you would not need a header file at all.
I am not sure why you placed call to LoadLibrary in the header file.
Since you are exporting class, you have to let the compiler know the type. Besides, you do not have to export entire class, you can export only specific member functions of the class you want to expose
Your dll header to be used in a dll and exe projects, should include following (I used my own names):
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif
class CWin32DLL
{
public:
CWin32DLL();
int WIN32DLL_API GetInt();
};
Implementation:
#include "stdafx.h"
#include "Win32DLL.h"
extern "C" WIN32DLL_API CWin32DLL* _getInstance()
{
return new CWin32DLL();
}
// This is the constructor of a class that has been exported.
// see Win32DLL.h for the class definition
CWin32DLL::CWin32DLL()
{
}
int CWin32DLL::GetInt()
{
return 42;
}
Your DLL consumer:
#include "Win32DLL.h"
#include "SomeOther.h"
typedef CWin32DLL* (*getInstanceFactory)();
HINSTANCE dllHandle = LoadLibrary(_T("Win32DLL.dll"));
getInstanceFactory factory_func = (getInstanceFactory)GetProcAddress(dllHandle, "_getInstance");
CWin32DLL* pWin32 = factory_func();
int iRet = pWin32->GetInt();
Do not forget to define WIN32DLL_EXPORTS (or equivalent) in project properties, C++, Preprocessor, Preprocessor Definitions for the dll.

c++ exporting and using dll function

I can't quite figure out where there is a mistake. I am creating a DLL and then using it in a C++ console program (Windows 7, VS2008). But I get LNK2019 unresolved external symbol when trying to use the DLL functions.
First the export:
#ifndef __MyFuncWin32Header_h
#define __MyFuncWin32Header_h
#ifdef MyFuncLib_EXPORTS
# define MyFuncLib_EXPORT __declspec(dllexport)
# else
# define MyFuncLib_EXPORT __declspec(dllimport)
# endif
#endif
This is one header file I then use in:
#ifndef __cfd_MyFuncLibInterface_h__
#define __cfd_MyFuncLibInterface_h__
#include "MyFuncWin32Header.h"
#include ... //some other imports here
class MyFuncLib_EXPORT MyFuncLibInterface {
public:
MyFuncLibInterface();
~MyFuncLibInterface();
void myFunc(std::string param);
};
#endif
Then there is the dllimport in the console program, which has the DLL included in the Linker->General->Additional Library Directories:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
__declspec( dllimport ) void myFunc(std::string param);
int main(int argc, const char* argv[])
{
std::string inputPar = "bla";
myFunc(inputPar); //this line produces the linker error
}
I can't figure out what's going wrong here; it must be something really simple and fundamental.
You're exporting a class member function void MyFuncLibInterface::myFunc(std::string param); but trying to import a free function void myFunc(std::string param);
Make sure you #define MyFuncLib_EXPORTS in the DLL project. Make sure you #include "MyFuncLibInterface.h" in the console app without defining MyFuncLib_EXPORTS.
The DLL project will see:
class __declspec(dllexport) MyFuncLibInterface {
...
}:
And the console project will see:
class __declspec(dllimport) MyFuncLibInterface {
...
}:
This allows your console project to use the class from the dll.
EDIT: In response to comment
#ifndef FooH
#define FooH
#ifdef BUILDING_THE_DLL
#define EXPORTED __declspec(dllexport)
#else
#define EXPORTED __declspec(dllimport)
#endif
class EXPORTED Foo {
public:
void bar();
};
#endif
In the project which actually implements Foo::bar() BUILDING_THE_DLL must be defined. In the project which tries to use Foo, BUILDING_THE_DLL should not be defined. Both projects must #include "Foo.h", but only the DLL project should contain "Foo.cpp"
When you then build the DLL, the class Foo and all its members are marked as "exported from this DLL". When you build any other project, the class Foo and all its members are marked as "imported from a DLL"
You need to import the class not a function. After that, you can call the class member.
class __declspec( dllimport ) MyFuncLibInterface {
public:
MyFuncLibInterface();
~MyFuncLibInterface();
void myFunc(std::string param);
};
int main(int argc, const char* argv[])
{
std::string inputPar = "bla";
MyFuncLibInterface intf;
intf.myFunc(inputPar); //this line produces the linker error
}