Wsutil.exe (Native Web Services Compiler): WCHAR* vs LPCWSTR for xsd:string type - wchar

Is there a good reason for the native web services compiler to generate a WCHAR * for an xsd:string vs a const wchar_t* (or LPCWSTR in short)?
The reason I state this question is that ours is a native c++ application which has std::wstrings floating around in the code that needs to be passed into a WCF service. In order to use the C functions generated by the native web services compiler it's forcing me to do something on the lines of e.g.
MyCppFunc(const std::wstring& inputString ,…)
{
…
HRESULT hr = BasicHttpBinding_BlahService(const_cast<<WCHAR*>WCHAR*>(inputString.c_str()), ….);
}
As seen from above I am forced to do away with the const on the pointer, my point of concern here is by explicitly having a WCHAR* type is the pointer data expected to get manipulated by the webservices.lib itself in anyway?
Alternatively I could end up copying over the contents of the string to a WCHAR* but for the fact that our c++ app runs as a service and we have heap fragmentation concerns over the frequent allocations/de-allocations.
Thanks.,
Raghu

Related

How to load COM dll modules and expose their interfaces as out of proccess servers

I have an out of process server based on the ATL Service VC++2010 Template. Now I wont to extend his COM Interface by dynamically loading additional dlls that contain its own COM Classes.
The dll to load is based on ATL dll VC++2010 Template, containing a simple ATL-object "IMModule". I changed the corresponding .rgs file to connect the class from the dll to the EXE server by adding a LocalServer section and the server's AppID as follows:
HKCR
{
NoRemove CLSID
{
ForceRemove {59276614-A811-4D27-B131-514656E643D3} = s 'IMModule Class'
{
ForceRemove Programmable
LocalServer32 = s 'path to the service exe'
{
val ServerExecutable = s 'path to the service exe'
}
TypeLib = s '{250685C7-CBD3-4FF8-A3A6-2AF668794CFC}'
Version = s '1.0'
val AppID = s '{7EFD508A-53C6-4EA0-B21A-D29277B86CBC}'
}
}
}
In a dll init() method called by the service after loading the dll I call CoRegisterClassObject to register the IMModule class object. But im not sure how to obtain the IUnknown interface pointer (second parameter to CoRegisterClassObject ). I tried the following:
CIMModule::_ClassFactoryCreatorClass* pClassFak =
new CIMModule::_ClassFactoryCreatorClass;
IUnknown* pUnk;
HRESULT hr =
pClassFak->CreateInstance(CIMModule::_ClassFactoryCreatorClass::CreateInstance,
IID_IIMModule, (LPVOID*)&pUnk);
But the call to CreateInstance fails with E_NOINTERFACE.
So, how to register my IMModule class implemented inside a dll to be available for COM clients from my out of process server?
With the help from Roman.R I get the behavior that I need. I can't say thank you enough, #roman-r. I will precisely describe what I did, so maybe someone can retrace the steps and give me some response.
First I created an ATL based Windows service (named UmbrellaService). Inside UmbrellaService I added a simple ATL-Object named Control and added the method:
FindMeAnInterface(BSTR moduleName, IDispatch** ppDispach);
Thats all with the VC++ Wizard. Then I fixed the Control.rgs file by adding:
val AppID = s '%APPID%'
Why has VC++ still such bugs after 17 years of evolution? (See
CoCreateInstance does not start or connect to ATL COM service)
Then I created an ATL-dll Project, named MyModule, with a "Module"
simple ATL-Object inside. The Module class has a method
testMethod (LONG a, LONG b, LONG* sum)"
The MyModule dll is registered as a in-proc server. Furthermore the dll has some classes
that makes the dll a plugin as I need it.
In the PreMessageLoop method of the UmbrellaService the MyModule dll will be loaded with LoadLibrary and through GetProcAddress the address of a factory creation method is obtained. The factory creation method returns a plugin-dependent FactoryClass that acts as a plugin entry point. This is my COM-independent plugin mechanism.
Now to export the module interface from the plugin dll through the UmbrellaService interface I did the following: On the FactoryClass I add the method:
IDispatch* getInterface();
In getInterface method I call
CoCreateInstance(__uuidof(Module), NULL , CLSCTX_INPROC_SERVER , __uuidof(IDispatch), (VOID**) &pDispatch);
and return the obtained IDispatch interface. The FactoryClass::getInterface method is called inside the Control::FindMeAnInterface method of the UmbrellaService after comparing the name passed to FindMeAnInterface with the name provided by the FactoryClass. FindMeAnInterface returns the then obtained IDispatch pointer to the client.
On the client side I import the tlb file from the UmbrellaService and the tlb from the apropriate plugin dll. I call testMethod as follows:
IControlPtr pControl(__uuidof(Control));
_bstr_t moduleName("Module");
IDispatchPtr moduleDisp = pControl->FindMeAnInterface(moduleName);
IModulePtr pModule(moduleDisp );
LONG res = pModule->testMethod(42,23);
This all works indeed, but I am not sure if this is the way to do it. Did I miss something about reference counting? Will the plugin DLL be loaded two times? First time through my plugin mechanism and second time through CoCreateInstance? Something else I should note?
Thanks for your help!
I could not find my code so far. But I did check one of my favorite websites, The Code Project. It used to be popular especially with older technologies like COM (yes, it is). I hope you're already convinced that you have to use COM instead of new WFC or another technology.
Please check good documentation and sample code # ATL COM EXE doc. I believe I used this web page as a start of my past project.
Good luck and have fun.

.Net COM Interop get running COM instance and assign it to RCW

I am creating a wpf application which need to interop with a third party tool(COM). the tool will be launched first and I will give some input in the tool. then he will launch my wpf application where again some input will be given.my wpf app need to interop with the running instance of a tool and execute some methods in the tool and get the result to my app.I tried using RCW. but RCW is just a proxy. I need a running instance of a tool to interact with. Can anybody help me out????????????
Edit: There is existing C++ code which does this, so how can this be translated to C#?
bool DisDriver::Create(CLSID clsid, DWORD ClsContext, LPCTSTR ServerName)
{
hRet = ::CoCreateInstanceEx(clsid,NULL,dwClsContext,strServerName==NULL?NULL:(&svrinfo),1,&multiqi);
if(hRet!=S_OK) {
#ifdef XYDISPDRIVER_DEBUG
_tprintf(_T("CoCreateInstance failed:"),hRet);
#endif
return false;
}
pDisp = (IDispatch*)(multiqi.pItf);
}
Type.GetType(prog.id),Activator.CreateInstance(type) will actually get the running instance of a com program which is the required one for this issue.

Consuming Wcf from classic asp (with datacontract)

I'm currently developing a WCF service (Service.svc) and I would like to consume it with classic ASP. Naturally, i first checked how to on Google and Mdsn Library. I managed to connect my service.
But here is the problem, i can call simple method like :
string GetData(int i)
But I have some DataContracts too a methods signed like this :
IsAvailRef[] AreAvailable(MyInType data)
\With IsAvailRef as DataContract and so is MyInType.
And when I call these methods, I've an Asp error 'ASP 0106 : 80020005' saying "A data type not supported has been detected."
So here is my question : Can't we use DataContract with VB script ?
This is the signature of my function in the library generated by regasm.exe like explained in this article : http://msdn.microsoft.com/en-us/library/ms752245.aspx
[id(0x60020000)]
HRESULT AreReferencesAvailable([out, retval] SAFEARRAY(_IsAvailRef*)* pRetVal);
I believe DataContract is a class and is not a valid VBScript subtype:
http://www.csidata.com/custserv/onlinehelp/vbsdocs/vbs6.htm
You can probably call it's methods, however I doubt you can store it in a variant.

Flex unable to find definition for type from WCF Service?

I have a WCF Service running SOAP and allowing Flex / Flash to connect to it using basicHttpBinding by using the 'Data' \ 'Import Web Service' option. Unfortunately when I consume and invoke this service within Flex it throws the following error...
Error: Cannot find definition for type
'http://schemas.datacontract.org/2004/07/System.Drawing::Size' at
mx.rpc.xml::XMLDecoder/decodeType()
...when using the following code...
// This will return an array of presentations
var service:PresentationAuthoring = new PresentationAuthoring();
var token:AsyncToken = service.getAllPresentationByClientId(
mClientId , mUserId , mWCFServiceHash );
token.addEventListener( ResultEvent.RESULT, onResult );
token.addEventListener( FaultEvent.FAULT, onFault );
This method returns an array of Presentation objects that are retreived by the service. At the moment there are no DataContracts and I'm allowing the POCO Presentation object to be serialised and punted out by the service that works fine. However, this class has a readonly property of the type System.Drawing.Size that derived from appropriate height and width properties. Looking through the generated code, it doesn't register a 'Size' class in the base import schema although it still seems to create a Size class.
An alternative has been to stop the derived property from being serialised using the [XmlIgnore] but that has not worked.
Ideally, I need a way of allowing my Flex application to communicate with my WCF service but it seems to choke on the System.Drawing.Size type and while I could change this, there are other framework types such as Point, Rectangle, etc, etc. that are utilised within the project. Has anyone else experienced this problem or can suggest an alternative approach to take?
[Please note that the WCF Service functions correctly when a .NET application consumes it.]
Kind regards and thanks in advance - S
Well the answer was to box the Size struct with a custom class that worked perfectly although it is somewhat irksome I might have to do this with (potentially) other native drawing structs. Ho hum.

.NET webservice using an instance of a parameter type?

I have a Windows forms project and a Web Service project in my solution, and I'm trying to call the web service and return a customer object as the result. The problem is that when I try to receive the return object, I get an error that it can't convert it. For example, here is the signature for my webservice:
Public Function GetDriverByID(ByVal DriverID As Integer) As Driver
And here is the code I'm using to call it:
Dim d As Driver = mywebserviceinstance.GetDriverByID(1)
But I receive this compile-time error (wsDrivers is the name of the web reference I've added to my form project): "Value of type ProjectNamespace.Common.wsDrivers.Driver cannot be converted to ProjectNamespace.Common.Driver"
This "Common" namespace contains the Driver class, and I'm not sure why the return class from the web service isn't just a generic "Driver", but is instead a "wsDrivers.Driver", and I can't convert it back. Anybody know how I can deal with this type mismatch?
EDIT: Thanks for the explanations - this actually makes it clear what it's doing. However, is there any way that I can force it to use the actual type instead of the proxy (or, rather, is there any way to convert between the "real" instance and the "proxy" instance), or do I have to serialize the properties before I send them over the wire, and then manually de-serialize the return values?
This is actually pretty common. What's happening is that the Web Service has defined in it the definitions of all the types used in the web service. When you add a reference to that web service, it auto-generates a proxy type in a sub namespace of your namespace. That is what is being returned by your web service when you call it.
However, you probably are also referencing the same library that the web service does seperately that contains the same type. That is the type that is expected when you Dim Driver. That's why there is a mismatch.
The web service reference in a VB.NET or C# project can reference any type of web service and is not limited to those provided by ASP.NET. That is why Visual Studio creates proxy classes for each object which can be retrieved from the web service.