WinRT IDL overload reflection through IMetaDataImport - windows-runtime

I'm not sure whether this is new in WinRT or existed before; in IDL, you can write declarations like this:
[uuid(E9C62AEE-1494-4A21-BB7E-8589FC751D9D)]
[version(0x06020000)]
[exclusiveto(Windows.Networking.Sockets.DatagramSocket)]
interface IDatagramSocketStatics : IInspectable
{
[overload("GetEndpointPairsAsync")] HRESULT GetEndpointPairsAsync(
[in] Windows.Networking.HostName* remoteHostName,
[in] HSTRING remoteServiceName,
[out] [retval] Windows.Foundation.IAsyncOperation
<Windows.Foundation.Collections.IVectorView
<Windows.Networking.EndpointPair*>*>** operation);
[overload("GetEndpointPairsAsync")] HRESULT GetEndpointPairsWithSortOptionsAsync(
[in] Windows.Networking.HostName* remoteHostName,
[in] HSTRING remoteServiceName,
[in] Windows.Networking.HostNameSortOptions sortOptions,
[out] [retval] Windows.Foundation.IAsyncOperation
<Windows.Foundation.Collections.IVectorView<
<Windows.Networking.EndpointPair*>*>** operation);
}
The intention apparently is that the WinRT operation "GetEndpointPairAsync" is overloaded twice, once as GetEndpointPairsAsync, and once as GetEndpointPairsWithSortOptionsAsync.
Is it possible to learn the two underlying operation names through IMetaDataImport? I need to find out in order to generate C code which calls these methods, and all I get from EnumMethods is the overloaded name.

Overloaded members will have the OverloadAttribute custom attribute, which specifies the unique name of the overload.
You can call IMetaDataImport::EnumCustomAttributes to enumerate the custom attributes of a method definition (MethodDef), identify the OverloadAttribute if one is present, and parse its string argument to get the unique name.

Related

Can I add 'operations' to runtimeclass in a winrt component

In the below code "RuntimeMethod1()" is an operation. It does not take any input parameters and does not give back any result.
Is this kind of method allowed in a runtime class?
I am getting compilation error for this runtime class. It says
expecting an identifier near "(" at line 7
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
If I remove "RuntimeMethod1()" from the class then it compiles fine and generates the projection and implementation types.
If it doesn't return a result then make its return type void.
Change line 7 in your IDL to the following:
void RuntimeMethod1();
Then either copy and paste the method from auto generated .h file or just add it manually.
With the exception of constructors, all methods in MIDL 3.0 need to declare a return type. The documentation has the following to say on methods:
A method has a (possibly empty) list of parameters, which represent values or variable references passed to the method. A method also has a return type, which specifies the type of the value computed and returned by the method. A method's return type is void if it doesn't return a value.
You will have to change the MIDL to the following:
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
void RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
Note, that the data types declared in MIDL follow MIDL specification. This is not strictly related to the Windows Runtime type system, although all MIDL data types map to data types that can be represented in the Windows Runtime type system.
Also note, that all methods in the Windows Runtime have at least one return value at the ABI. A method declared using void in MIDL will still return an HRESULT to communicate error or success.

generated Skel method missing Exception declaration in Tao_idl

I have one method in IDL(test.idl) file:
bool login(in string name, in string cipher) raises (AuthenticationException);
AuthenticationException is declared an exception in my IDL files. Then I use tao_idl to generate skeleton with below parameters:
-Wb,stub_export_macro=BASE_STUB_Export -Wb,stub_export_include=base_stub_export.h -Wb,skel_export_macro=BASE_SKEL_Export -Wb,skel_export_include=base_skel_export.h -GC
However, the generated login method in testS.h is like:
virtual ::project::UserContext * login (
const char * name,
const char * cipher) = 0;
and testI.h:
virtual
::project::UserContext * login (
const char * name,
const char * cipher);
This is strange to me. Because method declaration missing AuthenticationException exception. I believe that the method should be like:
login(..) throw(AuthenticationException)
in which custom exception, instead of CORBA standard exception, is thrown in business logic and client stub can catch these exception.
Is there something wrong in my tao_idl parameters?
No, there is nothing wrong with your tao_idl parameters, this is how the IDL to C++ mapping is defined. Older versions of IDL to C++ did use exception specifications in C++, but the recent ones don't, see the OMG IDL to C++ mapping which you can obtain from http://www.omg.org/spec/CPP.
Also the IDL to C++11 language mapping doesn't use exception specifications, this more modern C++ language mapping is also available from the OMG, see http://www.omg.org/spec/CPP11.
Your IDL method and the generated signature don't match, with IDL to C++11 your login method (with a boolean return type) in IDL looks like
virtual bool login (const std::string& name, const std::string& cipher) = 0;

Function objects in C++ (C++11)

I am reading about boost::function and I am a bit confused about its use and its relation to other C++ constructs or terms I have found in the documentation, e.g. here.
In the context of C++ (C++11), what is the difference between an instance of boost::function, a function object, a functor, and a lambda expression? When should one use which construct? For example, when should I wrap a function object in a boost::function instead of using the object directly?
Are all the above C++ constructs different ways to implement what in functional languages is called a closure (a function, possibly containing captured variables, that can be passed around as a value and invoked by other functions)?
A function object and a functor are the same thing; an object that implements the function call operator operator(). A lambda expression produces a function object. Objects with the type of some specialization of boost::function/std::function are also function objects.
Lambda are special in that lambda expressions have an anonymous and unique type, and are a convenient way to create a functor inline.
boost::function/std::function is special in that it turns any callable entity into a functor with a type that depends only on the signature of the callable entity. For example, lambda expressions each have a unique type, so it's difficult to pass them around non-generic code. If you create an std::function from a lambda then you can easily pass around the wrapped lambda.
Both boost::function and the standard version std::function are wrappers provided by the li­brary. They're potentially expensive and pretty heavy, and you should only use them if you actually need a collection of heterogeneous, callable entities. As long as you only need one callable entity at a time, you are much better off using auto or templates.
Here's an example:
std::vector<std::function<int(int, int)>> v;
v.push_back(some_free_function); // free function
v.push_back(&Foo::mem_fun, &x, _1, _2); // member function bound to an object
v.push_back([&](int a, int b) -> int { return a + m[b]; }); // closure
int res = 0;
for (auto & f : v) { res += f(1, 2); }
Here's a counter-example:
template <typename F>
int apply(F && f)
{
return std::forward<F>(f)(1, 2);
}
In this case, it would have been entirely gratuitous to declare apply like this:
int apply(std::function<int(int,int)>) // wasteful
The conversion is unnecessary, and the templated version can match the actual (often unknowable) type, for example of the bind expression or the lambda expression.
Function Objects and Functors are often described in terms of a
concept. That means they describe a set of requirements of a type. A
lot of things in respect to Functors changed in C++11 and the new
concept is called Callable. An object o of callable type is an
object where (essentially) the expression o(ARGS) is true. Examples
for Callable are
int f() {return 23;}
struct FO {
int operator()() const {return 23;}
};
Often some requirements on the return type of the Callable are added
too. You use a Callable like this:
template<typename Callable>
int call(Callable c) {
return c();
}
call(&f);
call(FO());
Constructs like above require you to know the exact type at
compile-time. This is not always possible and this is where
std::function comes in.
std::function is such a Callable, but it allows you to erase the
actual type you are calling (e.g. your function accepting a callable
is not a template anymore). Still calling a function requires you to
know its arguments and return type, thus those have to be specified as
template arguments to std::function.
You would use it like this:
int call(std::function<int()> c) {
return c();
}
call(&f);
call(FO());
You need to remember that using std::function can have an impact on
performance and you should only use it, when you are sure you need
it. In almost all other cases a template solves your problem.

Compare two interfaces using "is"

I am not sure if I am missing something here. I would like to compare two classes that uses the same interface. Is this possible? I understand that the is operator compares classes, but is there any similar function when you use interfaces?
// works
var effect1 : CrazyEffect = new CrazyEffect();
var effect2 : SaneEffect = new SaneEffect();
trace(effect1 is effect2) // false
// does not work
var effect1 : ISoundEffect = new CrazyEffect();
var effect2 : ISoundEffect = new SaneEffect();
trace(effect1 is effect2)
1067: Implicit coercion of a value of type ISoundEffect to an unrelated type Class.
Note the differences between concepts of a class and of an object. The former is a data type whereas the latter is a runtime instance of it, a variable. is operator can not compare one variable to another.
According to language reference
is Operator
Evaluates whether an object is compatible with a specific data type,
class, or interface. Use the is operator instead of the instanceof
operator for type comparisons. You can also use the is operator to
check whether an object implements an interface.
In other words, compiler expects the first operand to be a variable whereas the second operand should be a type identifier.
var sample:String = "Object is an instance of a class.";
^^^ ^^^
variable type identifier
However effect2 is not a type identifier but a variable. Hence the error message.
Unfortunately there is no generic operator to test for interface commonality. The only alternative is:
trace((s is ISoundEffect) && (t is ISoundEffect));
Update
Checking whether objects are instances of a same class can be done by comparing class names:
if (getQualifiedClassName(effect1) == getQualifiedClassName(effect2)) {
// true
}
For in depth discussion see Get the class used to create an object instance in AS3
Even though it will work with getQualifiedClassName, there's a better method to check whether two objects are instances of the same class:
a['constructor'] === b['constructor']
getQualifiedClassName is very slow and CPU intensive. Since the above code just compares property values it is lightning fast. And yes, constructor IS a property of every object, however FB will complain if you try to access it using dot-notation, that's why I use dynamic property access.

What Does "Overloaded"/"Overload"/"Overloading" Mean?

What does "Overloaded"/"Overload" mean in regards to programming?
It means that you are providing a function (method or operator) with the same name, but with a different signature.
For example:
void doSomething();
int doSomething(string x);
int doSomething(int a, int b, int c);
Basic Concept
Overloading, or "method overloading" is the name of the concept of having more than one methods with the same name but with different parameters.
For e.g. System.DateTime class in c# have more than one ToString method. The standard ToString uses the default culture of the system to convert the datetime to string:
new DateTime(2008, 11, 14).ToString(); // returns "14/11/2008" in America
while another overload of the same method allows the user to customize the format:
new DateTime(2008, 11, 14).ToString("dd MMM yyyy"); // returns "11 Nov 2008"
Sometimes parameter name may be the same but the parameter types may differ:
Convert.ToInt32(123m);
converts a decimal to int while
Convert.ToInt32("123");
converts a string to int.
Overload Resolution
For finding the best overload to call, compiler performs an operation named "overload resolution". For the first example, compiler can find the best method simply by matching the argument count. For the second example, compiler automatically calls the decimal version of replace method if you pass a decimal parameter and calls string version if you pass a string parameter. From the list of possible outputs, if compiler cannot find a suitable one to call, you will get a compiler error like "The best overload does not match the parameters...".
You can find lots of information on how different compilers perform overload resolution.
A function is overloaded when it has more than one signature. This means that you can call it with different argument types. For instance, you may have a function for printing a variable on screen, and you can define it for different argument types:
void print(int i);
void print(char i);
void print(UserDefinedType t);
In this case, the function print() would have three overloads.
It means having different versions of the same function which take different types of parameters. Such a function is "overloaded". For example, take the following function:
void Print(std::string str) {
std::cout << str << endl;
}
You can use this function to print a string to the screen. However, this function cannot be used when you want to print an integer, you can then make a second version of the function, like this:
void Print(int i) {
std::cout << i << endl;
}
Now the function is overloaded, and which version of the function will be called depends on the parameters you give it.
Others have answered what an overload is. When you are starting out it gets confused with override/overriding.
As opposed to overloading, overriding is defining a method with the same signature in the subclass (or child class), which overrides the parent classes implementation. Some language require explicit directive, such as virtual member function in C++ or override in Delphi and C#.
using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
An overloaded method is one with several options for the number and type of parameters. For instance:
foo(foo)
foo(foo, bar)
both would do relatively the same thing but one has a second parameter for more options
Also you can have the same method take different types
int Convert(int i)
int Convert(double i)
int Convert(float i)
Just like in common usage, it refers to something (in this case, a method name), doing more than one job.
Overloading is the poor man's version of multimethods from CLOS and other languages. It's the confusing one.
Overriding is the usual OO one. It goes with inheritance, we call it redefinition too (e.g. in https://stackoverflow.com/users/3827/eed3si9n's answer Line provides a specialized definition of Draw().