I want to build dlls using Visual Studio which I want to use as functions in Matlab.
While doing so I have used declspec(dllimport) function...but I get compilation error LNK2019: unresolved external sumbol?
Appreciate your help.
#ifdef PRC50CONTROL_EXPORTS
#define PRC50CONTROL_API __declspec(dllexport)
#else
#define PRC50CONTROL_API __declspec(dllimport)
#endif
int PRC50CONTROL_API SetPRC50Gain(double inGain);
int PRC50CONTROL_API SetPRC50Gain(double inGain);
You have the return type before the __declspec()
Move it to
PRC50CONTROL_API int SetPRC50Gain(double inGain);
Also, obviously, make sure you have
PRC50CONTROL_EXPORTS
defined in your header of the library you're exporting the symbols from.
Related
I'm trying to build a WIN32 console app that uses the current 2.12.28 ftd2xx.lib static library from FTDI. I'm using VS2013 and native unmanaged C++. My call looks like this.
#include "../ftd2xx.h"
. . .
DWORD port_count = 0;
FT_STATUS status = FT_OK;
status = FT_CreateDeviceInfoList(&port_count);
When I compile I get a link error
GetTopazVCP.obj : error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList#4 referenced in function "unsigned long __cdecl Get1stVirtualComPort(unsigned long *)" (?Get1stVirtualComPort##YAKPAK#Z)
The unresolved symbol __imp__FT_CreateDeviceInfoList#4 appears to be a mangled name version of the FT_CreateDeviceInfoList function. So it's not being resolved in the ftd2xx.lib which uses C naming. What I don't understand is why the compiler mangled the name when the ftd2xx.h file has a conditional extern "C"
#ifdef __cplusplus
extern "C" {
#endif
. . .
FTD2XX_API
FT_STATUS WINAPI FT_CreateDeviceInfoList(
LPDWORD lpdwNumDevs
);
...
#ifdef __cplusplus
}
#endif
wrapping all the FT_??? declarations. I have confirmed that __cplusplus is defined during the compile. Any ideas what is causing the unexpected name mangling?
As ChronoKitsune pointed out in his comment there is no name mangling here. The problem was I was linking the static version of the FTDI library but the default for the ftd2xx.h header file is to declare the FT_??? functions as calls to the DLL version. When I replaced the ftd2xx.lib static version with the ftd2xx.lib DLL version it built successfully. FTDI only supplies one version of the ftd2xx.h header and looking closely inside it I discovered that if you want to use the static ftd2xx.lib you need to #define FTD2XX_STATIC before including ftd2xx.h
#define FTD2XX_STATIC
#include "ftd2xx.h"
A Visual Studio C++ solution is made of 2 projects both in C++:
Client produces a client.exe
Algo produces a algo.dll
Client and Algo communicate together via a COM Layer, hence Algo is a COM dll.
I want to add a function in Algo.dll and call it directly from Client, avoiding the COM Layer, but did not succeed to solve the "unresolved symbol" link errors when building the Client.exe
What was tried ?
In the Algo project, I've added the LIBRARY_EXPORT preprocessor definition and the following files:
TestFile.h
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
extern "C" LIBRARY_API bool __stdcall TestFunction();
TestFile.cpp
extern "C" LIBRARY_API bool __stdcall TestFunction()
{
return true;
}
In the client project, there is a call to TestFunction();
I get an link error when building the client:
unresolved external symbol "__declspec(dllimport) bool __cdecl TestFunction(void)
Apparently, I do not get correctly how to export/import my function.
You need to add algo.lib to the linker input files of client.exe
first of all I have to mention that I'm new to c++ but within my course of studies I have gained some experiences with programming.
Currently, I'm working on a plugin for a datastream between vicon blade 1.7 and unreal engine 4.4.3. This should be done by using the Vicon Datastream SDK v 1.4 which contains a header file, a library and a .dll file.
Right now, I'm having problems with compiling my basic plugin.
The Vicon DataStream SDK was build within an older version of visual studio than 2010. So I want to know if there is any possibility to go on working with the vicon sdk in visual studio 2013? Should I force the sdk to use the latest .dll in visual studio and if so how do I do that?
I already tried to go on working with the sdk ignoring the problem I've mentioned before.
When I built the project without changing the header file of the sdk I'm getting this error:
Error 2 error C2059: syntax error : 'constant'
Here are the affected rows:
#ifdef WIN32
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif // _EXPORTING
#elif defined( __GNUC__ )
#if __GNUC__ < 4
#error gcc 4 is required.
#endif
#define CLASS_DECLSPEC __attribute__((visibility("default")))
#else
#define CLASS_DECLSPEC
#endif
#include <string>
namespace ViconDataStreamSDK
{
namespace CPP
{
...
}
}
If I redefine the second namespace to 'UCPP' I'm getting a huge list of errors like this one:
Error 2 error LNK2019: unresolved external symbol
"__declspec(dllimport) public: __cdecl
ViconDataStreamSDK::UCPP::Client::Client(void)"
I think it's because CPP is already defined in unreal engine but because of the dependency of the header file to the .dll file in the sdk the definition of the namespace is unchangeable in the sdk.
Is that expectation correct or am I on the wrong track?
I had similar problems with the name space. To fix that I did this in my UE4 Plugin header file before including the Vicon DataStreamSDK
#define UCPP CPP
#undef CPP
#include <Client.h> //Vicon DataStreamSDK
.....
At the end of this file I redifined the CPP macro
#define CPP PCPP
This compiles and works fine with no problems
I'm using visual studio 2010 to build a .dll. I wrote up a trial as:
// trialDLL.h
#ifndef TRIALDLL_H_
#define TRIALDLL_H_
// ... MyMathFuncs class definition omitted
#ifdef __cplusplus
extern "C"{
#endif
#ifdef TRIALDLL_EXPORT
#define TRIALDLL_API __declspec(dllexport)
#else
#define TRIALDLL_API __declspec(dllimport)
#endif
TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset);
TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath);
TRIALDLL_API double __stdcall MyAdd(MyMathFuncs* myMath, double a, double b);
// some other similar stuff
#ifdef __cplusplus
}
#endif
#endif
And the triallDLL.cpp file:
// trialDLL.cpp
#include "trialDLL.h"
TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset)
{
return new MyMathFuncs(offset);
}
TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath)
{
delete myMath;
}
TRIALDLL_API double __stdcall MyAdd(MyMathFuncs *myMath, double a, double b)
{
return myMath->Add(a, b);
}
// ... some other definitions
With these two files in the project, I added a property sheet to the project through visual studio 2010 property manager and added TRIALDLL_EXPORT to user macros. After all these, the nice Intellisense gives me error for each function defined in the .cpp file and complains "error: a function declared 'dllimport' may not be defined". So it appears that Intellisense doesn't find TRIALDLL_EXPORT defined. I thought it might make a difference if I actually build the project, but the result suggests the same error: "error C2491: 'new_MyMathFuncs' : definition of dllimport function not allowed". Then it is clear that the macro TRIALDLL_EXPORT is still not defined in compiling time.
After failing to add macro through visual studio, I also tried putting code line: #define TRIALDLL_EXPORT in trialDLL.cpp but it didn't help either. I wonder what's the proper way to do this? How do I inform the compiler that the micro is defined so that TRIALDLL_API evaluates to dllexport rather than dllimport?
Also, if I can build the .dll successfully, is there any systematic way to test/verify the functionality of the .dll?
Thanks for any help in advance! (Although I know it's an issue here on stackoverflow to put appreciation in the question, I feel myself impolite not to do so. Forgive me for any inefficiency caused by these lines.)
"User macros" in VS property sheets have nothing to do with preprocessor macros. Put TRIALDLL_EXPORT into the property sheet's section C/C++ > Preprocessor > Preprocessor Definitions
"User macros," which can only be defined in property sheets, allow you to create your own "variables" usable in Visual Studio properties, similar to the built-in ones $(TargetName), $(SolutionDir) etc.
As said in this Microsoft article, you cannot apply the __declspec(dllimport) keyword to implement a function. You should use it only in the declaration. For example:
// function declaration
void __declspec(dllimport) funcB();
// function definition
void funcB() {
//funcB code
}
Put
#error Where is my macro?
in the #else block of the header. Then experiment with the project settings or the #define until you get it right. Did you perhaps only add the property sheet to one configuration? Did you put the #define at the very top of the file? Do you have any PCH stuff that causes it to ignore your settings? And so on.
The code looks okay, and must work if TRIALDLL_EXPORT is actually defined. You most probably messed up that somehow (like set it for a different configuration or for just one file) or did not rebuild.
If you're completely lost, ask for the preprocessor output, and look at that. As with define there can not be dllimport around at all, the error is also impossible.
EDIT: I just noticed you wrote _I also tried putting code line: #define TRIALDLL_EXPORT in_ trialDLL.cpp. I thought you put it at top of the header for trial. Try that first just to see that it works fine. Then you can remove it after you found the proper place.
Here's the scenario:
Platform:
VS2005 and language is VC++
Situation:
There's just 1 assembly CMPW32. It has 2 projects:
1 is a DLL project called CMPW32 and the 2nd one is an .exe project called Driver
They both share the same Debug folder under the main assembly folder.
I have been able to successfully export a few functions from the DLL. The Driver project accesses 1 of these exported functions. (First of all I am not if functions need to be exported for projects in the SAME assembly to be able to use them. I can just include the header files and use the functions I think.)
Following is are a few lines of code from some files which you might find useful to analyze my problem:
//main.cpp file from the Driver project which is meant to generate Driver.exe
#pragma comment(lib, "winmm.lib")
#include <CM.h>
#include "conio.h"
#include "CMM.h"
#include "CMF.h"
#define C_M_F _T("c:\\CannedMessages.en-US")
int_tmain (int argc, TCHAR* argv [])
{
CMM myobjModel;
CMF::Read (CANNED_MESSAGES_FILE, myobjModel);
getch();
}
//CMM.h file
#ifndef C_M_M
#define C_M_M
#include "CMD.h"
#include "CMC.h"
#include "CM.h"
#define _C_M_DLL
#include "CMP.h"
class CM_DLL_API CMM
{ //some code here...
}
//CMF.h
#ifndef C_M_F
#define C_M_F
#include "CMM.h"
#define _C_M_DLL
#include "CMP.h"
class CM_DLL_API CMF
{ //some code here...
}
//CMP.h
#ifndef C_M_P
#define C_M_P
#include "CMD.h"
#define C_M_B_F _T("CannedMessages.")
#ifdef _C_M_DLL
#define CM_DLL_API __declspec( dllexport )
#else
#define CM_DLL_API __declspec( dllimport )
#endif
extern "C"
{
//list of functions to be exported..
}
ERRORS on building the solution:
Error13 error LNK2019: unresolved external symbol "public: __thiscall CMM::~CMM(void)" (??1CMM##QAE#XZ) referenced in function _wmain main.obj
Error15 fatal error LNK1120: 2 unresolved externals C:\"somepath here which I cant disclose"\Projects\CMPW32\Debug\Driver.exe
Please Note: If I choose to build only the CMPW32 DLL project, there are no errors and the CMPW32.dll file gets generated in the debug folder with the correct functions getting getting exported.
However there seems to be some linking problem that is pretty evident and I don't know what's going on. I have included every required file and also have entered the required .lib in the input of the "Project Settings". The paths have been set correctly too.
It would be really helpful if someone could help me out with this. Please lemme know if additional information required.
Thanks,
Viren
Looks like your Driver.exe project does not include the CPP source files of the CMM class, likely CMM.cpp.
or
You have declare a destructor for CMM class in your .H file (CMM.H) and forgot to implement it in the .CPP file (CMM.CPP).