How do I fix SvcUtil generating code with errors in it for a C++/CLI WCF client? - wcf

I've run into a problem with code generated by SvcUtil when generating a WCF client in C++/CLI.
When I run "SvcUtil.exe /t:code /l:cpp http://localhost:2772/mex/" it generates a header file containing the client class below.
[System::Diagnostics::DebuggerStepThroughAttribute,
System::CodeDom::Compiler::GeneratedCodeAttribute(L"System.ServiceModel", L"3.0.0.0")]
public ref class DemoClient : public System::ServiceModel::ClientBase<IDemo^ >, public IDemo
{
public: DemoClient();
public: DemoClient(System::String^ endpointConfigurationName);
public: DemoClient(System::String^ endpointConfigurationName, System::String^ remoteAddress);
public: DemoClient(System::String^ endpointConfigurationName, System::ServiceModel::EndpointAddress^ remoteAddress);
public: DemoClient(System::ServiceModel::Channels::Binding^ binding, System::ServiceModel::EndpointAddress^ remoteAddress);
public: virtual System::String^ GetDemoString() sealed;
};
This results in a lot of errors, which I would not have expected given it is generated code.
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closed::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closed::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closed::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closed::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closing::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closing::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Closing::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Closing::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Faulted::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Faulted::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Faulted::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Faulted::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opened::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opened::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opened::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opened::remove'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opening::add(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opening::add'
Demo.h(41): error C3766: 'DemoClient' must provide an implementation for the interface method 'void System::ServiceModel::ICommunicationObject::Opening::remove(System::EventHandler ^)' : see declaration of 'System::ServiceModel::ICommunicationObject::Opening::remove'
Any suggestions on what I need to change or add to correct this? Should I just add an implementation for the listed interface methods?

Since the link is broken you can use Wayback Machine to see the page
The relevant part from the post is
You should use the following workaround to get a successful compile:
Locate the full runtime assembly in:
%SysRoot%\Microsoft.NET\Framework\v4.0.30319\System.ServiceModel.dll
Copy this dll.
Replace the Reference Assembly in:
%ProgramFiles(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.ServiceModel.dll
Recompiling your project should now succeed.

Alternatively, just add required TargetFrameworkVersion in .vcxproj
example:
edit your .vcxproj to add TargetFrameworkVersion tag containing v4.7.2
within PropertyGroup at Globals scope
This should work without manually copying any dll.

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?

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?

Friend statement of singleton causing linker errors

I get linker errors when building my program. The problem seems to be my NetworkManager singleton gets pulled into Networkable with the friend statement. I read that this can happen when having the instance declaration in the .hpp file, but if the instance() function isn't being inlined in some way this shouldn't be my case.
I found similar questions here, but no one that answers my problem. Any suggestions?
// Networkable.hpp
#pragma once
class Networkable
{
friend class NetworkManager;
public:
....
//NetworkManager.hpp
#pragma once
class Networkable;
class NetworkManager
{
public:
static NetworkManager &instance();
~NetworkManager();
void registerNetworkable(Networkable *networkable);
void unregisterNetworkable(Networkable *networkable);
void update();
...
// errors:
1>NetworkManager.obj : error LNK2005: "public: __thiscall NetworkManager::~NetworkManager(void)" (??1NetworkManager##QAE#XZ) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: static class NetworkManager & __cdecl NetworkManager::instance(void)" (?instance#NetworkManager##SAAAV1#XZ) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::registerNetworkable(class Networkable *)" (?registerNetworkable#NetworkManager##QAEXPAVNetworkable###Z) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::unregisterNetworkable(class Networkable *)" (?unregisterNetworkable#NetworkManager##QAEXPAVNetworkable###Z) already defined in Networkable.obj
1>NetworkManager.obj : error LNK2005: "public: void __thiscall NetworkManager::update(void)" (?update#NetworkManager##QAEXXZ) already defined in Networkable.obj
Right, I'm ashamed to say I found the answer. I had included NetworkManager.cpp instead of .hpp in Networkable.cpp.
Guess that's what happen when late-night coding...
But it does somewhat raise a valid and easy to make typo - writing .cpp instead of .hpp and not "seeing" the problem. It's much easier to spot a typo with just .h, and makes me question the .hpp file naming standard...