Is there a way to avoid header files completely? - c++-cli

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?

Related

MIDL unresolved type declaration: IAsyncOperation<IInspectable>

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?

C++/CLI how to pass integer pointer to C++ API

Looks like I am doing a basic mistake here. I have a 3 party C++ library(test.dll) in which there is a API defined as follows. And I am invoking this APi by loading the library, getting the API and invoke. I am new to C++ CLI, any pointers to solve the issue will be helpful. Thanks in advance.
3rd part library exported API
FUNCTION_EXPORT void STDCALL GetVersion(UINT16& version);
typedef void (STDCALL *GETVERSION)(UINT16);
I need to call it from C++ Cli
Header file
MyTest.h
namespace MyTest {
public ref class TestClass
{
public:
HMODULE module;
String^ version;
void TestMethod()
};
}
Cpp file
MyTest.cpp
namespace MyTest {
TestClass::TestMethod()
{
this->module = LoadLibrary(engineDllPath);
if (!this->module)
{
return String::Format("LoadLibrary failed");
};
// Get engine version
GETVERSION GetVersionApi = (GETVERSION)GetProcAddress(module, "GetVersion");
if (!GetVersionApi)
{
return;
}
UINT16 major;
GetVersionApi(&uiMajor);
}
}
Getting compilation error
error C2664: 'void (UINT16 &)' : cannot convert parameter 1 from 'UINT16 *' to 'UINT16 &'
Code snippet is to give an idea what I am trying. The main issue is here
UINT16 major;
GetVersionApi(&uiMajor);
what will be the correct way of calling it. Please help.
GetVersion(UINT16& version);
That's not an integer pointer, that's an integer reference. You don't need to type any extra characters to pass a reference.
GetVersionApi(uiMajor);
// ^ no "&"

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' ]

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?