Syntax error : missing ';' before '^' in c++ managed - c++-cli

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?

Related

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.

Forward declaration and ComPtr

I have this simple case:
struct ID3D11Buffer;
class Object3D
{
Microsoft::WRL::ComPtr<ID3D11Buffer> indBuffer; // use of undefined type 'ID3D11Buffer' in VisualStudio 2013
std::shared_ptr<ID3D11Buffer> a; // ok
}
As you can see forward declaration works withshared_ptr, but fails with ComPtr. And I curious why?

How to use ObjC block typedefs in Swift2 (esp. when containing BOOL parameters)

After moving on to Xcode7 (beta5) and Swift 2, I'm getting errors in my Swift code regarding Bool (or BOOL / ObjCBool) values that are passed from (or into) closures with an Objective-C typedef.
typedef void (^completion_success_block_t) (BOOL success);
When I use this type in my Swift class, I'm getting compiler errors.
func doSomething(completionBlock : completion_success_block_t) {
doSomethingElse { success in
if success == true { } // (1) error 1
let foo : Bool = true
completionBlock(foo) // (2) error 2
completionBlock(true) // (3) works just fine!
}
}
// error 1: "Binary operator '==' cannot be applied to operands of type 'ObjCBool' and 'Bool'"
// error 2: "Cannot invoke 'completionBlock' with an argument list of type '(Bool)'"
func doSomethingElse(completionBlock : completion_success_block_t) {
completionBlock(true)
}
Why does line (3) compile just fine, but not line (2)?
It seems like the compiler does convert between ObjCBools and Bools in some cases but not always.
It feels like using my ObjC typedef is like telling the compiler: 'I really want this to be an ObjCBool, not a Bool, so please don't do any conversions for me'. But that's not what I want. My code was working perfectly fine in Xcode 6.
Now I only see two options:
1) convert all values manually before passing / using them: let swiftSuccess = Bool(success) and let objCFoo = ObjCBool(foo)
2) stop using the ObjC typedefs for blocks containing BOOL parameters
Is there a better way? Perhaps changing the block signature in the typedef to work with both Swift and ObjC? But how?
Cool! Apple fixed this in Xcode Version 7.0 (7A218). Now passing a Swift Bool to a closure that was an ObjC typedef with a BOOL parameter works just fine. Comparing the BOOL parameter with true or false in Swift works as well.
Only downside for me: now all my workaround lines of code (e.g. completionBlock(ObjCBool(true))) cause compiler errors (sometimes even of the slightly obscure Segmentation fault: 11 type). Have to revert it all back. Sigh... (thank god there's git)

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?