I'm been curious about the declaration syntax of Collections::Generic::Dictionary
class in C++/CLI.
Normally we declare a reference in a class and initialize it:
public ref class CDemo {
private: ClassA ^ m_InstanceA;
// Why the absence of '^'.
private: Dictionary<int, int> m_Dic;
CDemo() :
m_InstanceA(gcnew ClassA()),
m_Dic(gcnew Dictionary<int, int>())
{...}
};
Could someone explains please why should the '^' absent there?
What's more, if I were to use the dictionary above as a TValue of another dictionary,
I have to declare it like this:
Dictionary<T, Dictionary<T, T>^ > m_Dic; // A '^' in the TValue parameter, which is
// normal, but same question as above,
// I don't have to declare m_Dic as ^ ?
Thanks.
This is not specific to Dictionary. This syntax is a way to help map C++ semantics onto managed types. In general:
ref class A
{
ReferenceType m_obj;
};
is roughly equivalent to
class A : IDisposable
{
private ReferenceType m_obj;
void Dispose() { m_obj.Dispose(); }
}
in C# if ReferenceType implements IDisposable. It is perfectly possible to write
ref class A
{
ReferenceType^ m_obj;
};
This does not have the implicit IDisposable support. The other difference is that you can return a ReferenceType^ from a method, this is not supported with just plain ReferenceType. For example:
ref class A
{
ReferenceType^ m_obj;
ReferenceType^ GetIt() { return m_obj; }
};
will compile,
ref class A
{
ReferenceType m_obj;
ReferenceType GetIt() { return m_obj; } // won't compile
ReferenceType^ OtherGetIt() { return m_obj; } // neither will this
};
A similar distinction is provided for automatic (stack variables)
ReferenceType local;
local.Stuff();
is desugared by the compiler to
try {
ReferenceType^ local = gcnew ReferenceType();
local->Stuff();
} finally {
delete local; // invokes Dispose() (~ReferenceType)
}
These features bring the familiar idiom of RAII to C++/CLI with managed types.
EDIT:
Yes, the Dispose method of IDisposable is analogous to a C++ destructor. If ReferenceType doesn't implement IDisposable (doesn't have a dtor), and it is the only member, A will also not implement IDisposable (not have an implicit dtor). In C++/CLI you implement IDisposable by providing a dtor (for managed types).
Related
I have a base class (with which I want to simulate interfaces)
template<typename TType>
class Base
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}
and obviously a derived class
template<typename TType>
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}
but for some specific type I have the intention to specialize the 'GetTheObject'
template<>
SomeTemplatedClass<int> Derived<int>::GetTheObject()
{
return 5;
}
Visual Studio 2015 complains it cannot instantiate abstract class, when I try to use
Derived<int>
Providing even a throwing behavior to a template version
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() override
{
throw <something>;
}
}
Let everything compile.
So my question is: Why do i need to provide a generic behavior, when I have a specific one and the only one that is needed?
You don't need to implement the generic GetTheObject, but you need to declare it as non-pure. Otherwise your class is abstract.
template<typename TType>
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject();
}
You can specialise the function now.
You won't be able to instantiate any non-specialised derived objects (you will get linker errors).
You cannot make an abstract class into concrete by simply providing an implementation of its pure virtual member outside of the class.
class A { virtual void f() = 0; }; // A is abstract
void A::f() {} // A is still abstract
Templates are no different.
template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract
A function specialisation changes nothing.
template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract
template <> void A<42>::f() {} // srsly are you kidding?
If you want the generic case to be abstract and the specialised case concrete, you need to specialise the entire class, not just the pure function implementation.
It seems that override and finalspecifiers can be used in both declaration and definition. Is it possible to only use them at the declaration level ?
The override and final specifiers can only appear in member definitons if the definition is inside a class definition.
E.g.:
struct Base { virtual void foo() = 0 }
struct Derived : public Base { void foo() override { std::cout << "foo"; } // OK
struct Derived : public Base { void foo() override; }
void Derived::foo() override { std::cout << "foo"; } // Error!
// ^^ Definition outside class. ^^
In other words, if you put the definition of a member function outside of the class definition, then yes, the override and final specifiers should only be present in the declaration inside the class definition.
http://en.cppreference.com/w/cpp/language/final
I tested this int EMV_Init(EMV_PARAMS *params, EMV_HANDLE *hEMV) in C, it works well.
Now i want to call it in my java application by means of jna. This function is in a native library under windows (dll file).
EMV_PARAMS is a structure
typedef struct
{
HAL_UI_HANDLE ui;
HAL_SCR_HANDLE card;
HAL_PROPERTY_HANDLE property;
HAL_DATE_HANDLE date;
HAL_CRYPTO_HANDLE crypto;
HAL_CHV_HANDLE chv;
} EMV_PARAMS;
Note that all attributes in EMV_PARAMS is is an opaque structure like this typedef void * HAL_UI_HANDLE;
EMV_HANDLE is also an opaque structure : typedef void *EMV_HANDLE;
I need your help to fix the following error:
Exception in thread "main" java.lang.NullPointerException at
com.sun.jna.Structure.getFields(Structure.java:895)
at com.sun.jna.Structure.deriveLayout(Structure.java:1042)
at com.sun.jna.Structure.calculateSize(Structure.java:966)
at com.sun.jna.Structure.calculateSize(Structure.java:933)
at com.sun.jna.Structure.allocateMemory(Structure.java:360)
at com.sun.jna.Structure.<init>(Structure.java:184)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
I created a Java interface named "CInterface" which contains "EMV_PARAMS" class.
public interface CInterface extends Library
{
CInterface INSTANCE = (CInterface) Native.loadLibrary("path to dll", CInterface.class);
public int EMVCT_Init(EMV_PARAMS.ByReference params, Pointer hEMV);
public static class PARAMS extends Structure
{
public static class ByReference extends PARAMS implements Structure.ByReference {}
Pointer ui;
Pointer card;
Pointer property;
Pointer date;
Pointer crypto;
Pointer chv;
#Override
protected List getFieldOrder() {
// TODO Auto-generated method stub
return null;
}
}
}
java test class
public static void main(String[] args)
{
CInterface.EMV_PARAMS.ByReference emv_param = new
CInterface.EMV_PARAMS.ByReference();
int test= 0;
Pointer hEMV = null;
test=CInterfaceEMV.INSTANCE.EMVCT_Init(emv_param, hEMV);
System.out.println("test="+test);
}
Thank you for your attention
Your structure fields must be public, and you need to implement getFieldOrder().
I've got an interface with a simple signature:
namespace Serial {
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
and then a class type which implements the interface
namespace Serial {
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial {
public:
event MyEventClass MyEvent;
MySerial();
...
};
}
but elsewhere, as a default parameter to a function, I try to store a reference to a type MySerial as an ISerial ^
void
begin(
Serial::ISerial ^s = ref new Serial::MySerial
);
causes: error C1001: An internal error has occurred in the compiler.
when I remove the event from the class definition, everything compiles fine. I'm finding little information on this error.
I verified this on VS 2013 and it works with a few minor changes (all generated based on normal compiler errors, not an ICE). I don't have VS 2015 available right now, but will log a bug if it still repros.
First the struct (should be unchanged)
namespace Serial
{
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
Then the class (couple of changes noted below):
namespace Serial
{
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial{
public:
event MyEventClass^ MyEvent;
MySerial(){}
virtual uint16_t func1() { return 42; }
virtual uint16_t func2() { return 42; }
};
}
And the usage:
void foo()
{
using namespace Serial;
ISerial^ foo = ref new MySerial();
}
Basically you need to add the hat (^) to the event type, and you need to add virtual to the methods (but do not add override).
See more here on MSDN
Sorry for the vague title, but I'm not sure what this is called.
Say I add IDisposable to my class, Visual Studio can create the method stub for me. But it creates the stub like:
void IDisposable.Dispose()
I don't follow what this syntax is doing. Why do it like this instead of public void Dispose()?
And with the first syntax, I couldn't work out how to call Dispose() from within my class (in my destructor).
When you implement an interface member explicitly, which is what the generated code is doing, you can't access the member through the class instance. Instead you have to call it through an instance of the interface. For example:
class MyClass : IDisposable
{
void IDisposable.Dispose()
{
// Do Stuff
}
~MyClass()
{
IDisposable me = (IDisposable)this;
me.Dispose();
}
}
This enables you to implement two interfaces with a member of the same name and explicitly call either member independently.
interface IExplict1
{
string InterfaceName();
}
interface IExplict2
{
string InterfaceName();
}
class MyClass : IExplict1, IExplict2
{
string IExplict1.InterfaceName()
{
return "IExplicit1";
}
string IExplict2.InterfaceName()
{
return "IExplicit2";
}
}
public static void Main()
{
MyClass myInstance = new MyClass();
Console.WriteLine( ((IExplcit1)myInstance).InstanceName() ); // outputs "IExplicit1"
IExplicit2 myExplicit2Instance = (IExplicit2)myInstance;
Console.WriteLine( myExplicit2Instance.InstanceName() ); // outputs "IExplicit2"
}
Visual studio gives you two options:
Implement
Implement explicit
You normally choose the first one (non-explicit): which gives you the behaviour you want.
The "explicit" option is useful if you inherit the same method from two different interfaces, i.e multiple inheritance (which isn't usually).
Members of an interface type are always public. Which requires their method implementation to be public as well. This doesn't compile for example:
interface IFoo { void Bar(); }
class Baz : IFoo {
private void Bar() { } // CS0737
}
Explicit interface implementation provides a syntax that allows the method to be private:
class Baz : IFoo {
void IFoo.Bar() { } // No error
}
A classic use for this is to hide the implementation of a base interface type. IEnumerable<> would be a very good example:
class Baz : IEnumerable<Foo> {
public IEnumerator<Foo> GetEnumerator() {}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
Note how the generic version is accessible, the non-generic version is hidden. That both discourages its use and avoids a compile error because of a duplicate method.
In your case, implementing Dispose() explicitly is wrong. You wrote Dispose() to allow the client code to call it, forcing it to cast to IDisposable to make the call doesn't make sense.
Also, calling Dispose() from a finalizer is a code smell. The standard pattern is to add a protected Dispose(bool disposing) method to your class.