I am working on making a game engine. The engine is dll project. Right now the engine builds to a dll and lib. I am trying to test what I have so far with with another project. This is the error messages that I get:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Aria::GameConfig::GameConfig(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (__imp_??0GameConfig#Aria##QAE#ABV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###Z) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) D:\My Documents\Programing\Repo\NDTD\NDTD\Project\Main.obj
error LNK2019: unresolved external symbol "public: __thiscall TestGame::TestGame(class Aria::GameConfig *)" (??0TestGame##QAE#PAVGameConfig#Aria###Z) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) D:\My Documents\Programing\Repo\NDTD\NDTD\Project\Main.obj
error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup D:\My Documents\Programing\Repo\NDTD\NDTD\Project\MSVCRTD.lib(crtexe.obj)
Here part of my platform.h file that has the dll import and export macros
#if !defined(ARIA_STATIC)
#ifdef ARIA_SYS_WINDOWS
#if defined (ARIA_NONCLIENT_BUILD)
// define dllexport and dllimport macros
#ifndef ARIA_API
#define ARIA_API __declspec(dllexport)
#endif
#else
#ifndef ARIA_API
#define ARIA_API __declspec(dllimport)
#endif
#endif
// Visual c++ compiler warning C4251 disable
#ifdef _MSC_VER
#pragma warning(disable : 4251)
#endif
#else // Linux and MAC OS X
#if __GNUC__ >= 4
// GCC 4 has unique keywords for showing/hiding symbols
// the same keyword is used for both import and export
#define ARIA_API __attribute__ ((__visibility__("default")))
#define ARIA_API __attribute__ ((__visibility__("default")))
#else
#define ARIA_API
#define ARIA_API
#endif
#endif
#else
// static build doesn't need import/export macros
#define ARIA_API
#define ARIA_API
#endif
In I have built the engine with the preprocessor definition ARIA_NONCLIENT_BUILD and UNICODE and windows it defined. I have linked to SDL lib and included the header files. I am also using unicode strings with wchar. I also have not forgotten to add the ARIA_API macro in class definitions.
In the test project here is the main.cpp file
#include <Game\Game.h>
using namespace Aria;
class TestGame : public IGame
{
public:
TestGame(GameConfig* config);
~TestGame();
void OnStartUp() override;
void OnUpdate(float dt) override;
void OnRender(float dt) override;
void OnShutdown() override;
};
void TestGame::OnStartUp()
{
}
void TestGame::OnUpdate(float dt)
{
}
void TestGame::OnRender(float dt)
{
}
void TestGame::OnShutdown()
{
}
int main()
{
GameConfig* config = new GameConfig(ATEXT("test.config"));
TestGame* game = new TestGame(config);
return game->Run();
}
If I have forgot something then let me know.
Related
Im trying to write a wrapper in c++/cli for an DLL, which code i dont have, only DLL file and header but i created lib file through VS command prompt. When i`m trying to build solution i receive this errors:
DotNetWrappOfAsterSdkDll.obj : error LNK2028: unresolved token (0A00002E) "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
DotNetWrappOfAsterSdkDll.obj : error LNK2019: unresolved external symbol "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
I tried to create my own DLL and include it to the wrapper, and its working perfectly
here dll created by me which i can use in c++/cli wrapper:
//header file
#pragma once
#define DLLEXP __declspec( dllexport )
namespace Computations {
DLLEXP void someMethod(int number);
}
//cpp file
#include "Computations.h"
#include <iostream>
#include <time.h>
//#include "pnl/pnl_random.h"
using namespace std;
void Computations::someMethod(int number)
{
std::cout << "something "<<number*number << endl;
}
and here is part of header of DLL which i want to use:
#ifndef MUTEIFC_H
#define MUTEIFC_H
#include <Windows.h>
#ifdef MUTEIFC_LIBRARY
# define MUTEAPI extern "C"__declspec(dllexport)
#else
# define MUTEAPI __declspec(dllimport)
#endif
#define MUTECALL __stdcall
/** \ingroup init */
/** Initialization of the ASTER SDK library
* \returns TRUE - success, FALSE - failure (use \ref MuteLastErrorCode or/and \ref MuteLastErrorInfo to get
* failure cause)
* \note This function will require Administrative privileges on the first call on a given computer.
*/
MUTEAPI BOOL MUTECALL MuteIfcInitialize(VOID);
/** \ingroup init */
/** Finialization of the ASTER SDK library
*/
MUTEAPI VOID MUTECALL MuteIfcFinalize(VOID);
/** \ingroup errors*/
/** Clears the calling thread's last-error code and description.
* The last-error is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error.
*/
MUTEAPI VOID MUTECALL MuteClearLastError(VOID);
#endif // MUTEIFC_H
and my c++/cli code :
//header file
#pragma once
#include "Computations.h"
#include "muteifc.h"
using namespace System;
namespace DotNetWrappOfAsterSdkDll
{
public ref class WrapperClass2
{
public:
void doMuteClearLastError();
};
public ref class WrapperClass
{
private:
public:
void getPriceCallEuro(int number);
};
}
//cpp file
#include "DotNetWrappOfAsterSdkDll.h"
using namespace DotNetWrappOfAsterSdkDll;
using namespace Computations;
namespace DotNetWrappOfAsterSdkDll
{
//this dont work
void WrapperClass2::doMuteClearLastError() {
MuteClearLastError();
}
//this works great
void WrapperClass::getPriceCallEuro(int number) {
someMethod(number);
//MuteIfcFinalize();
}
}
Please tell me what i'm doing wrong
You probably didn't add the lib that contains the function reference to the linker options.
Either the lib contains he code it self or it has a reference to the DLL that must be loaded. The linker will bring your code and the DLL (or static lib) code together...
I'm trying to build a C++/CLI library in Visual Studio 2012 (on Win8 Release Preview) to use the functions InitializeTouchInjection and InjectTouchInput in C#.
I define my class like so
// MultiTouchWrapper.h
namespace MultiTouchWrapper {
public ref class MultiTouchInjection
{
public:
static bool InitializeMultiTouch(int maxCount);
static bool InjectMultiTouch(int count, float *x, float *y, int *id);
};
}
and implement the functions
//MultiTouchWrapper.cpp
#include "stdafx.h"
#include "MultiTouchWrapper.h"
namespace MultiTouchWrapper{
bool MultiTouchInjection::InitializeMultiTouch(int maxCount){
if(InitializeTouchInjection(maxCount, TOUCH_FEEDBACK_DEFAULT)) return true;
return false;
}
bool MultiTouchInjection::InjectMultiTouch(int count, float *x, float *y, int *id){
POINTER_TOUCH_INFO *contacts = new POINTER_TOUCH_INFO[count];
for(int i=0; i<count; i++){
contacts[i].pointerInfo.pointerType = PT_TOUCH;
contacts[i].pointerInfo.pointerId = id[0];
contacts[i].pointerInfo.ptPixelLocation.y = (LONG)y[0];
contacts[i].pointerInfo.ptPixelLocation.x = (LONG)x[0];
contacts[i].touchFlags = TOUCH_FLAG_NONE;
contacts[i].touchMask = TOUCH_MASK_NONE;
}
if(InjectTouchInput(count, contacts)) return true; //defined like this to avoid a warning about BOOL vs bool.
return false;
}
In stdafx.h I include <windows.h>, which gives the definition of InitializeTouchInjection and InjectTouchInput through <WinUser.h>.
The problem I'm running across is that when I try to build this library, I get the errors LNK2028 and LNK2019 for both functions:
Error 1 error LNK2028: unresolved token (0A00003B) "extern "C" int __stdcall InjectTouchInput(unsigned int,struct tagPOINTER_TOUCH_INFO const *)" (?InjectTouchInput##$$J18YGHIPBUtagPOINTER_TOUCH_INFO###Z) referenced in function "public: static bool __clrcall MultiTouchWrapper::MultiTouchInjection::InjectMultiTouch(int,float *,float *,int *)" (?InjectMultiTouch#MultiTouchInjection#MultiTouchWrapper##$$FSM_NHPAM0PAH#Z) C:\Users\mediascape\documents\visual studio 2012\Projects\MultiTouchWrapper\MultiTouchWrapper\MultiTouchWrapper.obj MultiTouchWrapper
Error 2 error LNK2028: unresolved token (0A000063) "extern "C" int __stdcall InitializeTouchInjection(unsigned int,unsigned long)" (?InitializeTouchInjection##$$J18YGHIK#Z) referenced in function "public: static bool __clrcall MultiTouchWrapper::MultiTouchInjection::InitializeMultiTouch(int)" (?InitializeMultiTouch#MultiTouchInjection#MultiTouchWrapper##$$FSM_NH#Z) C:\Users\mediascape\documents\visual studio 2012\Projects\MultiTouchWrapper\MultiTouchWrapper\MultiTouchWrapper.obj MultiTouchWrapper
Error 3 error LNK2019: unresolved external symbol "extern "C" int __stdcall InitializeTouchInjection(unsigned int,unsigned long)" (?InitializeTouchInjection##$$J18YGHIK#Z) referenced in function "public: static bool __clrcall MultiTouchWrapper::MultiTouchInjection::InitializeMultiTouch(int)" (?InitializeMultiTouch#MultiTouchInjection#MultiTouchWrapper##$$FSM_NH#Z) C:\Users\mediascape\documents\visual studio 2012\Projects\MultiTouchWrapper\MultiTouchWrapper\MultiTouchWrapper.obj MultiTouchWrapper
Error 4 error LNK2019: unresolved external symbol "extern "C" int __stdcall InjectTouchInput(unsigned int,struct tagPOINTER_TOUCH_INFO const *)" (?InjectTouchInput##$$J18YGHIPBUtagPOINTER_TOUCH_INFO###Z) referenced in function "public: static bool __clrcall MultiTouchWrapper::MultiTouchInjection::InjectMultiTouch(int,float *,float *,int *)" (?InjectMultiTouch#MultiTouchInjection#MultiTouchWrapper##$$FSM_NHPAM0PAH#Z) C:\Users\mediascape\documents\visual studio 2012\Projects\MultiTouchWrapper\MultiTouchWrapper\MultiTouchWrapper.obj MultiTouchWrapper
I'm not sure what to do. I've tried including /LD in the Configuration Properties >> C/C++ >> Command Line menu. I've tried changing the calling convention to __cdecl in the Advanced menu, but it always reverts back to __stdcall.
Any help on what to do to get around these linker errors?
I did not link to the user32.lib file. For those wondering what needed to be done, I used this question as a reference to figure out where to go and what the problem was.
I made a DLL with a function named "render()" and I want to load it dynamically to my application, but GetProcAddress cannot find it. Here's the DLL .h:
#ifdef D3D_API_EXPORTS
#define D3D_API_API __declspec(dllexport)
#else
#define D3D_API_API __declspec(dllimport)
#endif
D3D_API_API void render();
And here's DLL .cpp:
#include "stdafx.h"
#include "D3D_API.h"
#include <iostream>
D3D_API_API void render()
{
std::cout << "method called." << std::endl;
}
Here's the application that tries to use that function:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE myDLL = LoadLibrary( L"D3D_API.dll" );
if (myDLL == NULL) {
std::cerr << "Loading of D3D_API.dll failed!" << std::endl;
}
typedef void (WINAPI *render_t)();
render_t render = (render_t)GetProcAddress( myDLL, "render" );
if (render == NULL) {
std::cerr << "render() not found in .dll!" << std::endl;
}
return 0;
}
My goal is to make a 3D engine that supports both D3D and OpenGL through their own .DLLs using a unified API. I looked at the .dll in notepad and there was a string "render".
The function you export is treated as a C++ function (because of *.cpp file extension) and so C++ name mangling is used to decorate the exported function name. If you use the Dependency Walker tool from Microsoft to inspect your created DLL you will see the functions full name.
You can either use that decorated name in your import code or force the compiler to export your function in C style, that is, in its undecorated form that your current import code expects.
You can tell the compiler to do so by adding extern "C" to your functions signature. Something like this:
extern "C" D3D_API_API void render();
Now your import code should work as expexted.
As the comment to the answer says:
using 'extern "C"' will remove any C++ name mangling, but still leaves
C name mangling. In order to export the plain names you should look at
using a .DEF file. See
blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533
You need to add a new file with .DEF extension to your project, with similar to this contents:
LIBRARY "MyRenderLib"
EXPORTS
render
Then in your DLL header you don't use __declspec(dllexport), but only extern "C"
extern "C" void render();
I declare a singleton on a MFC extension DLL, like this:
//header file: SingleTon.h
class AFX_EXT_CLASS CMySingleton
{
public:
static CMySingleton* Instance()
{
if(!singleton)
singleton = new CMySingleton();
return singleton;
}
int a;
// Other non-static member functions
private:
CMySingleton() {}; // Private constructor
CMySingleton(const CMySingleton&); // Prevent copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent assignment
virtual ~CMySingleton() {};
static CMySingleton* singleton;
};
And in a cpp file I code the following line:
CMySingleton* CMySingleton::singleton = NULL;
Code 2:
CMySingleton *a;
a = CMySingleton::Instance();
The problem is when I code "code 2" in a Regular Dll, all works fine, but when I code "code 2" in another MFC extension DLL gives an error:
unresolved external symbol "private: static class CMySingleton* CMySingleton::singleton" (?singleton#CMySingleton##0PAV1#A)
I check correctly all the dependencies, via Project Dependencies.
Any idea?
The problem is in the AFX_EXT_CLASS macro.
#ifdef _AFXEXT
#define AFX_EXT_CLASS __declspec(dllexport)
#else
#define AFX_EXT_CLASS __declspec(dllimport)
#endif
Extension dll defines _AFXEXT and your class is exported, and main app (or a regular dll) doesn't define it so it's imported. But your second extension dll also defines _AFXEXT and your class declaration uses dllimport instead of dllexport and you get a linker error. The solution is to create your own macro for both dlls and use them instead of AFX_EXT_CLASS:
#ifdef EXTENSION_ONE
#define EXT_CLASS_ONE __declspec(dllexport)
#else
#define EXT_CLASS_ONE __declspec(dllimport)
#endif
Create EXTENSION_TWO and EXT_CLASS_TWO for your second dll. Define EXTENSION_ONE only in your first extension dll project, and EXTENSION_TWO only in your second extension dll project.
hej.h
void hej();
hej.m
void hej(){}
main.mm
#import "hej.h"
int main(int argc, char *argv[])
{
}
This gives me:
"hej()", referenced from:
_main in main.o
symbol(s) not found
If I rename main.mm to main.m (single m), or hej.m to mm or cpp, then it works. (Though none of those "solutions" are preferable. Imagine you want to use a c-lib in a objc++ environment - you wouldn't wanna change the entire lib, maybe even couldn't, and you need to use it in objc++.)
What exactly is going on here?
When compiled in a C file (*.c, *.m), the declaration void hej() generates a linker reference to a C function named _hej. When compiled in a C++ file (*.cc, *.mm, etc.), the declaration generates a linker reference to a C++ 'mangled name', that includes in it a description of the arguments. (This is done to support function overloading, e.g. to differentiate void hej(int) from void hej(char*)). hej.m always creates the C name. When main.mm references the C++ name, it won't be found.
To resolve, ensure main.mm looks for a C name, not a C++ one. If you control hej.h, it's common to add something like the following, which would work when hej.h is included in either a C or a C++ file:
/* hej.h */
#ifdef __cplusplus
extern "C" {
#endif
void hej();
#ifdef __cplusplus
}
#endif
If you do not own hej.h, you could do the following in main.mm instead:
extern "C" {
#import "hej.h"
}
int main(int argc, char *argv[])
{
}