MIDL unresolved type declaration: IAsyncOperation<IInspectable> - c++-winrt

In my C++/WinRT project I use below MIDL code to declare an asynchronous method returning a Windows::Foundation::IInspectable object.
namespace myproject
{
[default_interface]
runtimeclass FileRetriever
{
FileRetriever();
Windows.Foundation.IAsyncOperation<Windows.Foundation.IInspectable> RetrieveFileNamesAsync();
}
}
The code gives the following error when compiling:
Error MIDL2011 [msg]unresolved type declaration [context]: Windows.Foundation.IInspectable [ parameterized interface parameter 'Windows.Foundation.IInspectable' of Procedure 'RetrieveFileNamesAsync' ( RuntimeClass 'myproject.FileRetriever' ) ]
MSDN states the error can be resolved by "add[ing] an import directive for the IDL file(s) that contain the definitions of any type(s) that you reference that you've defined in your project" but IInspectable is obviously not a type I defined myself.
How can I resolve the error?

Related

Why can I not access `::class.companionObject`?

I am trying to access the companion object of an unknown class with a known interface, given an instance of the class.
Code below:
class AccessTest() {
companion object {
val prop = 5
}
fun getComp() {
print(this)
print(this::class)
print(this::class.companionObject) // Unresolved reference.
print(this::class.companionObjectInstance) // Unresolved reference.
}
}
inline fun <reified T> getCompanion() {
print(T::class.companionObject) // Unresolved reference.
print(T::class.companionObjectInstance) // Unresolved reference.
}
fun main() {
AccessTest().getComp()
getCompanion<AccessTest>()
}
Output:
$ kotlinc -d main.jar main.kt && kotlin -classpath main.jar MainKt
main.kt:8:27: error: unresolved reference: companionObject
print(this::class.companionObject) // Unresolved reference.
^
main.kt:9:27: error: unresolved reference: companionObjectInstance
print(this::class.companionObjectInstance) // Unresolved reference.
^
main.kt:14:20: error: unresolved reference: companionObject
print(T::class.companionObject) // Unresolved reference.
^
main.kt:15:20: error: unresolved reference: companionObjectInstance
print(T::class.companionObjectInstance) // Unresolved reference.
^
I do not think this is a duplicate of either of the below questions, as I am specifically asking what has changed or what I am misunderstanding such that the solution in the two below questions is not working for me:
how to access companion object from object instance in kotlin?
Kotlin invoke companion function with reflection
After a short discussion in comments, it turned out it was just a missing import.
companionObject is not a member of KClass, but extension on it, so it is possible we have access to KClass object, but we don't see its companionObject property. Also, as it's the part of kotlin-reflect library, it is not located in kotlin.reflect package, but in kotlin.reflect.full, so importing kotlin.reflect.* isn't enough to get it.

Typedef Return-Type in Objective-C does not work in Swift

I want to use a Objective-C class in my Swift project and have imported the files and Xcode created the bridge header file and everything is cool... except:
The Objective-C class defines a callback type for a function
typedef void (^SSScanManagerCallback)(BOOL success, NSError *error, NSArray *scannedURLs);
And uses the type in the function declaration
- (void)scanSync:(SSScanManagerCallback)callback; // Synchronous scan.
The class in question is the following: https://github.com/counsyl/scanstream/blob/master/ScanStream/SSScanManager.h#L16
If I then want to use the class in Swift:
let scanManager = SSScanManager();
scanManager.scanSync({(_ success: Bool, _ error: Error, _ scannedURLs: [Any]) -> Void in
if !success {
// ...
}
});
I get the following error:
Cannot convert value of type '(Bool, Error, [Any]) -> Void' to expected argument type 'SSScanManagerCallback!'
Update: Even if I try to set the argument type like so:
scanManager.scanSync({(_ justATry: SSScanManagerCallback!) -> Void in
});
I get the error:
Cannot convert value of type '(SSScanManagerCallback!) -> Void' to expected argument type 'SSScanManagerCallback!'
But how would I set the type to just 'SSScanManagerCallback!' as requested in the error message?
Interestingly, it appears that Swift (tested with 3.0.2) now imports Objective-C block argument types without any nullability annotations as strong optionals (previously they were imported as implicitly unwrapped optionals). I can't seem to find the documentation for this change though.
So in your case, the correct signature is:
scanManager.scanSync {(success: Bool, error: Error?, scannedURLs: [Any]?) -> Void in
// ...
}
But never write it like this, always let Swift infer the argument types where it can, it solves these kinds of type-mismatch problems for you.
scanManager.scanSync { success, error, scannedURLs in
// ...
}
Now you can ⌥ click on the closure arguments and Xcode will tell you the type that Swift infers them to be.

How to reference an external typelib from an interface defined for proxy/stub generation

I have an interface IFoo that references the Office typelib MSO.DLL. I want the proxy/stub code (dlldata.c) to be generated for my interfaces when my IDL is compiled. As I understand it, in order for midl.exe to produce the proxy/stub code, the interface(s) must be declared at the root level of my IDL. However, the importlib statements can only be within the library block. Consequently, the type I'm trying to reference (Office._CustomXMLParts) doesn't exist when IFoo is compiled. Is there any way to solve this, other than custom proxy/stub implementation or using IDispatch instead of the full referenced type?
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(02F84D34-91DB-400B-94C9-71ABCD6F077D),
version(1.0),
nonextensible,
pointer_default(unique),
oleautomation,
dual
]
interface IFoo : IDispatch
{
[id(0x461A47A4)] HRESULT Bar([in] Office._CustomXMLParts* customXmlParts);
};
[
uuid(CC76135E-FA22-4437-8719-3FFADE38D72B),
version(1.0)
]
library FooLib
{
importlib("stdole2.tlb");
importlib("mso.dll");
interface IFoo;
}
The error I receive is:
error MIDL2025: syntax error : expecting a type specification near "Office"
I tried moving the interface definitions below the library block, but I get a different error.
error MIDL2009: undefined symbol : _CustomXMLParts [ Parameter 'customXmlParts' of Procedure 'Bar' ]

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?