Friend statement of singleton causing linker errors - singleton

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

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

Is there a way to avoid header files completely?

I would like to know if there's a way of declaring a ref class in a cpp file and then reference it in another ref class in another cpp file. both ref classes would be in the same namespace. This is what I'm trying to do:
//class1.cpp
namespace nm
{
public ref class class1
{
};
}
//class2.cpp
namespace nm
{
public ref class class2
{
private:
class1^ _member;
};
}
I get 2 strange errors from the compiler and one a bit clearer from Intellisense:
error C2143: syntax error : missing ';' before '^'
error C4430: missing type specifier - int assumed. Note: C++
does not support default-int
IntelliSense: identifier "class1" is undefined
If I use header files all this goes away. Is there a way to make it work without the need for header files? Do I need a smarter compiler?

Syntax error : missing ';' before '^' in c++ managed

In my_project.h :
#pragma once
#include <vcclr.h>
#include "MyManagedClass.h"
namespace my_namespace
{
MyManagedClass^ DoSomething(const Foo* foo);
}
I have got next errors:
1) error C2143: syntax error : missing ';' before '^'
2) error C4430: missing type specifier - int assumed.
Note: C++ does not support default-int
Project has been created as c++/cli.
in "MyManagedClass.h" :
public ref class MyManagedClass
{
public:
System::UInt32 GetMember()
{
return m_member;
}
private:
System::UInt32 m_member;
};
In other files everything works but here, what I did wrong ?
ETA:
I've modified the function like this:
namespace my_namespace
{
MyManagedClass^ DoSomething(const System::String^ str);
}
And it didn't solve the problem, but for some reason if I change return type to void, then everything works fine
I re-created your issue, and got the same error. Removing the parameter const Foo* foo (making method DoSomething take no parameters) removed the error. I also tried adding typedef char* Foo;, and the error went away as well.
Check your definition of Foo, it looks like that's where the error is.
I copied & pasted your code into Visual Studio, there was no error on the MyManagedClass type. You'll need to show us more code if we're going to find the error.
Perhaps is MyManagedClass in a namespace that you forgot the using namespace directive for?

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

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.

How do I fix SvcUtil generating code with errors in it for a C++/CLI WCF client?

I've run into a problem with code generated by SvcUtil when generating a WCF client in C++/CLI.
When I run "SvcUtil.exe /t:code /l:cpp http://localhost:2772/mex/" it generates a header file containing the client class below.
[System::Diagnostics::DebuggerStepThroughAttribute,
System::CodeDom::Compiler::GeneratedCodeAttribute(L"System.ServiceModel", L"3.0.0.0")]
public ref class DemoClient : public System::ServiceModel::ClientBase<IDemo^ >, public IDemo
{
public: DemoClient();
public: DemoClient(System::String^ endpointConfigurationName);
public: DemoClient(System::String^ endpointConfigurationName, System::String^ remoteAddress);
public: DemoClient(System::String^ endpointConfigurationName, System::ServiceModel::EndpointAddress^ remoteAddress);
public: DemoClient(System::ServiceModel::Channels::Binding^ binding, System::ServiceModel::EndpointAddress^ remoteAddress);
public: virtual System::String^ GetDemoString() sealed;
};
This results in a lot of errors, which I would not have expected given it is generated code.
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closed::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closed::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closed::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closed::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closing::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closing::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closing::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closing::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Faulted::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Faulted::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Faulted::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Faulted::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opened::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opened::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opened::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opened::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opening::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opening::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opening::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opening::remove'
Any suggestions on what I need to change or add to correct this? Should I just add an implementation for the listed interface methods?
Since the link is broken you can use Wayback Machine to see the page
The relevant part from the post is
You should use the following workaround to get a successful compile:
Locate the full runtime assembly in:
%SysRoot%\Microsoft.NET\Framework\v4.0.30319\System.ServiceModel.dll
Copy this dll.
Replace the Reference Assembly in:
%ProgramFiles(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.ServiceModel.dll
Recompiling your project should now succeed.
Alternatively, just add required TargetFrameworkVersion in .vcxproj
example:
edit your .vcxproj to add TargetFrameworkVersion tag containing v4.7.2
within PropertyGroup at Globals scope
This should work without manually copying any dll.