unresolved token - c++ - c++-cli

I am trying to solve a lesson in my study. I am going to have an abstract class, CFigure, on top and different figures below, currently I have made a circle class. I am going to call this from a C# program.
But when I try to build my code I get the following error messages:
unresolved token (06000001) arealBeregnerCPP.CFigure::area
unresolved token (06000002) arealBeregnerCPP.CFigure::circumference
2 unresolved externals
I hope anyone can give me a hint in what I do wrong... Thanks!
This is my program:
// arealBeregnerCPP.h
#pragma once
using namespace System;
namespace arealBeregnerCPP {
public ref class CFigure
{
public:
virtual double area();
virtual double circumference();
};
public ref class CCircle : public CFigure
{
private:
double m_radius;
public:
CCircle(double radius)
{
m_radius = radius;
}
virtual double area() override
{
return 0; //not implementet
}
virtual double circumference() override
{
return 0; //not implementet
}
};
}

if CFigure::area() and CFigure::circumference() are abstract functions then put = 0 in declaration:
virtual double area() = 0;
virtual double circumference() = 0;

Probably you haven't defined area and circumference.
Since you fail to present complete code there are some other possibilities, such as failing to link with the relevant files.
By the way, please don't tag c++/cli questions as c++. Microsoft's c++/cli is not c++. It's a language similar to c++, but it's not c++.
Cheers & hth.,

Related

Passing native class pointer to another C++/CLI

I have two wrappers written in C++/CLI as followings.
One wrapper get a native class handle and it send this native handle to another class, however, I got a compile error.
I think there are some work-around,
1) #pragme make_public()
2) using IntPtr(sender) and static_cast with IntPtr.ToPointer(receiver).
What is the best solution?
namespace AWrapper {
public ref class AClass
{
public:
NativeClass* GetInfo() { return nativeClass; }
...
private:
NativeClass* nativeClass;
}
namespace BWrapper {
...
void ImageSensor::SetClass(AWrapper::AClass^ aclass)
{
NativeClass* native_tpr;
native_tpr = aclass->GetInfo(); // Not visible, like private
}
}

Mocking and Expecting from a Class instance created using new operator in Google Mock

Need your inputs regarding the below:
I am facing an issue regarding how to write a mock for a base class (StackBT) of which an instance is created in the derived class's constructor (ApplicationBT) that I want to test.
My intention is to write a mock for the StackBT class (Mock_StackBT) and then link this to the unit test so that the instance of the mock is created when doing "new StackBT()" in ApplicationBT's constructor. So that using this I can mock the expectations on StackBT class while testing ApplicationBT class.
out/linux_host/obj/TestApplicationBT.o: In function `TestApplicationBT::SetUp()':
tst/_src/TestApplicationBT.cpp:33: undefined reference to `mockPtr_StackBT'
out/linux_host/lib/libServer.a(ApplicationBT.o): In function `ApplicationBT::init()':
/_src/ApplicationBT.cpp:36: undefined reference to `StackBT::registerCallbacks()'
/_src/ApplicationBT.cpp:43: undefined reference to `StackBT::sendBTMacAddress(std::string)'
collect2: error: ld returned 1 exit status
make: *** [out/linux_host/bin/Test] Error 1
I get the above compiler error while compiling the below code snippet:
StackBT.h:
class StackBT
{
StackBT(){}
void registerCallbacks();
void sendBTMacAddress(std::string str);
}
Mock_StackBT.h:
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <string>
using ::testing::NiceMock;
class Mock_StackBT;
extern NiceMock < Mock_StackBT >* mockPtr_StackBT;
class Mock_StackBT: public StackBT
{
Mock_StackBT(){}
MOCK_METHOD0(registerCallbacks, void());
MOCK_METHOD1(sendBTMacAddress, void(std::string str));
}
Mock_StackBT.cpp:
#include "Mock_StackBT.h"
NiceMock < Mock_StackBT >* mockPtr_StackBT;
void registerCallbacks()
{
mockPtr_StackBT->registerCallbacks();
}
void sendBTMacAddress(std::string str)
{
mockPtr_StackBT->sendBTMacAddress(std::string str);
}
ApplicationBT.h:
class ApplicationBT
{
public:
ApplicationBT() : mpoStackBT(new StackBT())
void init()
{
mpoStackBT->registerCallbacks();
mpoStackBT->sendBTMacAddress("AB:CD:EF:GH:IJ:KL");
}
friend class TestApplicationBT;
scoped_ptr<StackBT> mpoStackBT;
}
TestApplicationBT.h
class TestApplicationBT : public ::testing::Test
{
protected:
virtual void SetUp ()
{
mockPtr_StackBT = &stackBTMock;
ptrApplicationBT = new ApplicationBT();
}
void TearDown()
{
delete ptrApplicationBT;
}
public:
TestApplicationBT ()
{
}
~TestApplicationBT ()
{
ptrApplicationBT = NULL;
}
scoped_ptr<ApplicationBT> ptrApplicationBT;
StackBT* ptrStackBT;
NiceMock<Mock_StackBT> stackBTMock;
};
TEST_F(TestApplicationBT, Init)
{
EXPECT_CALL(stackBTMock, registerCallbacks() ).Times(1);
EXPECT_CALL(stackBTMock, sendBTMacAddress(_) ).Times(1);
ptrApplicationBT->init();
}
First problem is that you are using mockPtr_StackBT in TestApplicationBT.cpp, but it is defined in
Mock_StackBT.cpp. The second issue is that the call to ApplicationBT::init method calls functions
registerCallbacks and sendBTMacAddress through pointer mpoStackBT, but if you look closely at
the constructor for class ApplicationBT you will se that this pointer is set to an object of class StackBT
and not Mock_StackBT. This causes a linker error because you did not implement functions
registerCallbacks and sendBTMacAddress for class StackBT, you have only declared them.
The main problem is that you are not swapping your real implementation with a mock, your approach is
not correct. First of all, you are not suppossed to create implementations for functions registerCallbacks
and sendBTMacAddress in the mock class, googlemock does that for you (file Mock_StackBT.cpp is completely
unnecessary). Also, you need a common interface for classes StackBT and Mock_StackBT so you can
switch implementations. Here is how you do it:
Create interface:
class IStackBT
{
public:
virtual IStackBT() {}
virtual void registerCallbacks() = 0;
virtual sendBTMacAddress(std::string str) = 0;
}
Create class for production:
class StackBT : public IStackBT
{
public:
void registerCallbacks() override
{
// Your code that registers callbacks
}
void sendBTMacAddress(std::string str) override
{
// Your code that sends mac address
}
}
Create mock class:
class StackBTMock : public IStackBT
{
public:
MOCK_METHOD0(registerCallbacks, void());
MOCK_METHOD1(sendBTMacAddress, void(std::string str));
}
Now, make your class ApplicationBT hold a IStackBT pointer and use some form of factory method
to create a real or mock object, depending on the fact if you are building unit test or deployment code. There
are several ways, here is how I did it on my gmock project. Create a preprocessor define for your unit testing
project that indicates the code is built for unit tests. If it is, for example, named MY_UNIT_TESTS, then in
constructor of ApplicationBT do the following:
ApplicationBT() : mpoStackBT(createStackBT())
where createStackBT is a function defined as:
IStackBT * createStackBT()
{
#ifdef MY_UNIT_TESTS
return new StackBTMock;
#else
return new StackBT;
#endif
}
This will perform the swapping of implementation during compilation time when you are building your unit test executable. Since you will be performing this swapping on several classes as you write more tests, I suggest that you wrap the factory functions in some class that provides the desired implementations (mock or production) of your classed. For instance, my project has a class named ImplementationProvider that performs this task.

C++/CLI: Passing C++ class ptr to unmanaged method

I've been given a third party C/C++ library (.dll, .lib, .exp and .h) that I need to use in our C# app.
ThirdPartyLibrary.h contains...
class AClass {
public:
typedef enum {
green = 7,
blue = 16
} Color;
virtual int GetData()=0;
virtual int DoWork(Color, char *)=0;
};
void * Func1(int, AClass **aClass);
In my C++/CLI code I have done this...
#include "ThirdPartyLibrary.h"
using namespace System;
using namespace System::Runtime::InteropServices;
namespace Wrapper {
public ref class MyBridgeClass
{
private:
AClass* pAClass;
public:
// C# code will call this method
void AMethod (int x)
{
int y = x+10;
Func1 (y, &(this->pAClass)); // <-- error!
}
}
}
I get a build error that reads...
cannot convert parameter 2 from 'cli::interior_ptr<Type>' to 'AClass **'
with
[
Type=AClass *
]
Cannot convert a managed type to an unmanaged type
Any ideas? Maybe I need #pragma manage/unmanged tags in my C++/CLI?
The reason you're getting that error is because of how managed memory works.
In your managed class, you've got a pointer defined. The address of that pointer is part of the managed object, and can change when the garbage collector runs. That's why you can't just pass &pAClass to the method, the GC can change what that address actually is.
There's a couple things you can do to fix this:
You could create an unmanaged helper class to hold the AClass* member. I'd do this if that pointer needs to stay valid beyond the invocation of this method, or if you have a lot of unmanaged pointers to hold.
struct UnmanagedHolder
{
AClass* pAClass;
};
public ref class MyBridgeClass
{
private:
// must create in constructor, delete in destructor and finalizer.
UnmanagedHolder* unmanaged;
public:
// C# code will call this method
void AMethod (int x)
{
int y = x+10;
Func1 (y, &(this->unmanaged->pAClass));
}
};
If you only need the pointer to be valid within AMethod, and the pointer doesn't need to remain valid after the call to Func1, then you can use a pin_ptr.
void AMethod (int x)
{
int y = x+10;
pin_ptr<AClass*> pin = &(this->pAClass);
Func1 (y, pin);
}

C++ CLI Wrapper

I’ve a question about creating a C++ CLI Wrapper for a native C++ class to be used in C#.
Here is an example code:
#include "stdafx.h"
#pragma once
using namespace System;
namespace Wrapper {
class NativeClass
{
public:
NativeClass() {}
int Add(int a, int b)
{
return a+b;
}
};
public ref class Wrapper
{
public:
Wrapper() {pNative = new NativeClass();}
int Add(int a, int b)
{
return(pNative->Add(a,b));
}
~Wrapper()
{
delete pNative;
pNative = 0;
}
!Wrapper()
{
this->~Wrapper();
}
//My problem is here.
NativeClass* GetNative()
{
return pNative;
}
private:
NativeClass* pNative;
};
}
This code works fine. I need to retrieve the pointer that refers the native class to use it in the other wrapper classes. However, I don’t want the function “GetNative” to be visible in C# when I’m using this wrapper class. How can I hide it?
If the other wrapper classes are in the same assembly, make the access internal instead of public. – Roger Rowland Apr 25 '13 at 9:47
.
if they are not in the same assembly? ...
Look into friend assemblies – Sebastian Cabot Feb 1 at 15:43

C++/CLI, "constant" reference to a tracking handle

I have spotted something like this in code:
void foo(IList<int>^ const & list ) { ... }
What does this ^ const& mean? I looked in the C++/CLI specification, but found no comments on making constant tracking references, nor the ^& combo.
Is this legal?
This code was probably written by a C++ programmer that used common C++ idiom to write C++/CLI. It is quite wrong, passing a reference to tracking handle is only possible if the handle is stored on the stack. It cannot work if the passed List<> reference is stored in a field of an object on the heap, the garbage collector can move it and make the pointer invalid. The compiler will catch it and generate an error. The ^ is already a reference, no additional reference is needed.
Without the reference, the const keyword doesn't make a lot of sense anymore either. Not that it ever did before, the CLR cannot enforce it. Not that this mattered much here, this code could not be called from any other .NET language. They won't generate a pointer to the tracking handle.
Just fix it, there's little point in keeping bad code like this:
void foo(IList<int>^ list ) { ... }
Example of code that shows that the reference cannot work:
using namespace System;
using namespace System::Collections::Generic;
ref class Test {
public:
IList<int>^ lst;
void foo(IList<int> const &list) {}
void wontcompile() {
foo(lst); // C3699
IList<int>^ okay;
foo(okay);
}
};
It's a reference which is constant to a tracking handle.
It allows you to pass the handle by reference instead of by value. Presumably the author thinks it's more efficient than copying the handle.
If the author meant to make the handle constant he should have used either of
Method(TestClass const ^ const & parameter)
Method(TestClass const^ parameter)
Or alternatively
Method(TestClass const^& parameter) - but the caller must const up the handle first
with
TestClass const^ constHandle = nonConstHandle
An example of each:
// test.cpp : Defines the entry point for the console application.
#include "stdafx.h"
ref class TestClass
{
public:
void setA(int value)
{
a = value;
}
TestClass() :
a(10)
{
}
private:
int a;
};
class TakesHandle
{
public:
void methodX1(TestClass const ^ const & parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
void methodX2(TestClass const^ parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
void methodX3(TestClass const^& parameter)
{
// Un-commenting below causes compiler error
// parameter->setA(11);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TakesHandle takes;
TestClass ^ test1 = gcnew TestClass();
// compiles
takes.methodX1(test1);
// compiles
takes.methodX2(test1);
TestClass const ^ constHandle = test1;
takes.methodX3(constHandle);
return 0;
}