In managed C++ how to define generic method that returns a value of specified type - c++-cli

I am trying to declare an equivalent of this code in c#:
public T FieldValueOrDefault<T>(int columnIndex);
I am using managed C++ Visual Studio 2015. If it matters, Target Platform Version is set to 8.1 and CLR Support set to /clr. When I enter something like this:
generic<typename T>
T FieldValueOrDefault<T>(String^ columnName);
I get a compiler error "Error C2768 FieldValueOrDefault': illegal use of explicit template arguments"
Please let me know what is a correct way to declare such thing.

It should be, as pointed out here:
generic<typename T>
T FieldValueOrDefault(String^ columnName);
The <T> is superfluous.

Related

How can I tell the Kotlin compiler that a Java method will never return null?

I don't or can't modify the Java source code. The goal to configure just the Kotlin compiler to know what is nullable and what isn't.
You can specify the type manually if you know something will never be null. For example, if you have the following Java code:
public static Foo test() {
return null;
}
and you call it in Kotlin like this:
val result = Foo.test()
then result will have a type of Foo! by default – which means it can be either Foo or Foo?.. the compiler doesn't have enough information to determine that.
However, you can force the type manually:
val result: Foo = Foo.test()
// use "result" as a non-nullable type
Of course, if at runtime that is not true, you'll get a NullPointerException.
For reference, please check the documentation.
I don't know of a way to configure the compiler for this, but IntelliJ IDEA has a feature that allows you to add annotations to code via an XML file called external annotations.
You can add the Jetbrains #Nullable and #NotNull annotations to library code, but when I've tried it, it only results in compiler warnings rather than errors when you use incorrect nullability in your code. These same annotations generate compiler errors when used directly in the source code. I don't know why there is a difference in behavior.
You can use extension functions for this. If you have a method String foo() in the class Test, you can define the extension function
fun Test.safeFoo(): String = this.foo()!!
The advantage is that the code is pretty obious.
The disadvantage of this approach is that you need to write a lot of boiler plate code. You also have to define the extension function in a place where all your modules or projects can see it. Also, writing that much code just to avoid !! feels like overkill.
It should also be possible to write a Kotlin compiler extension which generates them for you but the extension would need to know which methods never return null.

CLI/C++ function overload

I am currently writing a wrapper for a native C++ class in CLI/C++. I am on a little GamePacket class at the moment. Consider the following class:
public ref class GamePacket
{
public:
GamePacket();
~GamePacket();
generic<typename T>
where T : System::ValueType
void Write(T value)
{
this->bw->Write(value);
}
};
I want that I'm able to call the function as following in C#, using my Wrapper:
Packet.Write<Int32>(1234);
Packet.Write<byte>(1);
However, I can't compile my wrapper. Error:
Error 1 error C2664: 'void System::IO::BinaryWriter::Write(System::String ^)' : cannot convert argument 1 from 'T' to 'bool'
I don't understand this error, where does the System::String^ comes from. I'm seeing a lot of overloads of the Write() method, does CLI/C++ not call the correct one, and if so, how can I make it call the correct one?
Reference MSDN: http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write(v=vs.110).aspx
Templates and generics don't work the same.
With templates, the code gets recompiled for each set of parameters, and the results can be pretty different (different local variable types, different function overloads selected). Specialization makes this really powerful.
With generics, the code only gets compiled once, and the overload resolution is done without actually knowing the final parameters. So when you call Write(value), the only things the compiler knows is that
value can be converted to Object^, because everything can
value derives from ValueType, because your constraint tells it
Unfortunately, using just that information, the compiler can't find an overload of Write that can be used.
It seems like you expected it to use Write(bool) when T is bool, Write(int) when T is int, and so on. Templates would work like that. Generics don't.
Your options are:
a dozen different copies of your method, each of which has a fixed argument type that can be used to select the right overload of BinaryWrite::Write
find the overload yourself using reflection, make a delegate matching the right overload, and call it
use expression trees or the dynamic language runtime to find and make a delegate matching the right overload, and then you call it

C++/CLI optional arguments

Why i cannot declare default arguments for member functions of a managed type or generic functions? C# 4.0 introduced Named and Optional Arguments; there is a similar thing for CLI?
I do not understand why is not possible to declare a method like this:
void Optional(int argument = 0);
And then when I call Optional(); the compiler does not translate this call into: Optional(0);.
It looks like the C++/CLI Compiler doesn't emit the correct IL directive for that. It doesn't emit the directive .param [1] = int32(0), which C# uses for recognizing default parameters. If you open the generated assembly in ILDasm, you'll see it.
A way that compiles would be to use the attributes Optional and DefaultParameterValue from the System::Runtime::InteropServices namespace, but C# doesn't use those for default parameters, so currently there's no easy way around creating an overload.
You can find the question asking about those Attributes here: https://stackoverflow.com/a/4974528/93652

Representing IUnknown In Managed C++

I building Wrapper in C++/CLI for C Static library to be used in .NET application through C#
I have function like this in C
long My_COM_Interface( PVOID hDevice,IUnknown **pUnknown);
How to declare IUnknown ** in C++/CLI
for first argument I am using IntPtr but Not able to find out the Replacement for IUknown.
I have another COM Data type GUID in another function this is also an issue for me.
Please Help me find the relacement for data type IUnknown and GUID.
There is no replacement.
C++/CLI understands native types just fine. Include the right header files, and you can use IUnknown* like always.
I'd refer to the APIs, e.g.
public static IntPtr GetIUnknownForObject(Object o);
This API can simply be used from C++/CLR and suggests you should use IntPtr^
try using parameter like;
ref object pUnknown
and use it like
MyObject o = pUnknown as MyObject

How to convert from C# ref type to CLI\C++ ^% type

I am writing an application in Managed C++ (CLI\C++). In which I am using a library (.dll file) which is written in C#.
In a file I am encountering a problem.
I am implementing functions of an interface which is written in the library.
The declaration of a function in the library is as given below:
COMWORKSPACELib.IWorkspaceEvents.WorkspaceMessage(int, string, COMWORKSPACELib.EnumNotificationCode, COMWORKSPACELib.EnumNotificationType, string, ref COMWORKSPACELib.EnumNotificationReply);
When I write the same code in CLI\C++ the declaration is like:
WorkspaceMessage(int workspaceToken, String ^description, EnumNotificationCode ^code, EnumNotificationType ^type, String ^source, EnumNotificationReply ^%action);
Here, the compiler is giving me error that the “class must provide an implementation for the interface method”. Because the parameters passed in both function declarations are syntactically different.
Is there any alternative way to match the library declaration?
If I remove the “^’ & ‘%’ to match the library declaration then it gives further errors in the code.
Are EnumNotifcationCode, EnumNotificationType, and EnumNotficationReply all enums? That is, are they value types? If so, then it should be declared as follows:
WorkspaceMessage(int workspaceToken,
String^ description,
EnumNotificationCode code,
EnumNotificationType type,
String^ source,
EnumNotificationReply% action);