C++/CLI application for InjectTouchInput API. LNK2028 and LNK2019 errors - dll

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.

Related

why i can't wrap methods from one dll but can do it for another?

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...

C++/CLI how to pass integer pointer to C++ API

Looks like I am doing a basic mistake here. I have a 3 party C++ library(test.dll) in which there is a API defined as follows. And I am invoking this APi by loading the library, getting the API and invoke. I am new to C++ CLI, any pointers to solve the issue will be helpful. Thanks in advance.
3rd part library exported API
FUNCTION_EXPORT void STDCALL GetVersion(UINT16& version);
typedef void (STDCALL *GETVERSION)(UINT16);
I need to call it from C++ Cli
Header file
MyTest.h
namespace MyTest {
public ref class TestClass
{
public:
HMODULE module;
String^ version;
void TestMethod()
};
}
Cpp file
MyTest.cpp
namespace MyTest {
TestClass::TestMethod()
{
this->module = LoadLibrary(engineDllPath);
if (!this->module)
{
return String::Format("LoadLibrary failed");
};
// Get engine version
GETVERSION GetVersionApi = (GETVERSION)GetProcAddress(module, "GetVersion");
if (!GetVersionApi)
{
return;
}
UINT16 major;
GetVersionApi(&uiMajor);
}
}
Getting compilation error
error C2664: 'void (UINT16 &)' : cannot convert parameter 1 from 'UINT16 *' to 'UINT16 &'
Code snippet is to give an idea what I am trying. The main issue is here
UINT16 major;
GetVersionApi(&uiMajor);
what will be the correct way of calling it. Please help.
GetVersion(UINT16& version);
That's not an integer pointer, that's an integer reference. You don't need to type any extra characters to pass a reference.
GetVersionApi(uiMajor);
// ^ no "&"

LNK2019 unresolved external __declspec(dllimport) SDL_main

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.

Friend statement of singleton causing linker errors

I get linker errors when building my program. The problem seems to be my NetworkManager singleton gets pulled into Networkable with the friend statement. I read that this can happen when having the instance declaration in the .hpp file, but if the instance() function isn't being inlined in some way this shouldn't be my case.
I found similar questions here, but no one that answers my problem. Any suggestions?
// Networkable.hpp
#pragma once
class Networkable
{
friend class NetworkManager;
public:
....
//NetworkManager.hpp
#pragma once
class Networkable;
class NetworkManager
{
public:
static NetworkManager &instance();
~NetworkManager();
void registerNetworkable(Networkable *networkable);
void unregisterNetworkable(Networkable *networkable);
void update();
...
// errors:
1>NetworkManager.obj : error LNK2005: "public: __thiscall NetworkManager::~NetworkManager(void)" (??1NetworkManager##QAE#XZ) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: static class NetworkManager & __cdecl NetworkManager::instance(void)" (?instance#NetworkManager##SAAAV1#XZ) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::registerNetworkable(class Networkable *)" (?registerNetworkable#NetworkManager##QAEXPAVNetworkable###Z) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::unregisterNetworkable(class Networkable *)" (?unregisterNetworkable#NetworkManager##QAEXPAVNetworkable###Z) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::update(void)" (?update#NetworkManager##QAEXXZ) already defined in Networkable.obj
Right, I'm ashamed to say I found the answer. I had included NetworkManager.cpp instead of .hpp in Networkable.cpp.
Guess that's what happen when late-night coding...
But it does somewhat raise a valid and easy to make typo - writing .cpp instead of .hpp and not "seeing" the problem. It's much easier to spot a typo with just .h, and makes me question the .hpp file naming standard...

Working with structures in C++/CLI

I have following code
ref class A
{
typedef ref struct All
{
std::string x;
}All_t;
};
in my program I am using it in following manner
A::All_t t;
t.X = "H";
This declaration throwing error as
error C4368: cannot define 'x' as a member of managed 'A::All': mixed types are not supported
I understand that I am declaring native varible inside managed code which is not allowed but now I would like to know changes I will need to make to make my structure suitable to managed project.
Thanks.
I'm assuming you originally had std::string x; not std::string *x (since using the pointer to string does not generate that error). You are not allowed to directly embed a native type in a managed type, but you are allowed to indirectly have one (via a pointer) See:
http://msdn.microsoft.com/en-us/library/xhfb39es(v=vs.80).aspx
After I fixed the compiler errors in your sample, it builds without error:
#include "stdafx.h"
#include <string>
using namespace System;
ref class A
{
public:
typedef ref struct All
{
std::string * x;
}All_t;
};
int main(array<System::String ^> ^args)
{
A::All_t t;
t.x = new std::string("H");
return 0;
}