|
No, I am trying to authenticate the client, so I don't trust whatever it tells me.
I guess this is an issue common to all Local RPC. Does the server always trust the client running on the same machine?
|
|
|
|
|
I suspect the standard COM security API[^]s are the only real way to authenticate the client.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
In normal C++ when a class header only contains a reference or a pointer to a class it is better to not #include the definition but wait until the .cpp file to avoid coupling/avoid recompilation.
In our of our class headers the reference concerned is to a smart pointer generated from a #import, in other words a smart pointer of the form _COM_SMARTPTR_TYPEDEF(IComInterface, &__uuidof(IComInterface))
Which expands to typedef _com_ptr_t<_com_IIID<icominterface,> > IComInterface;
I think the problem is that the __declspec(uuid("GUID VALUE")) which is attached to the forward declaration of the IComInterface struct like __stdcall and __fastcall is part of the declaration and so will produce different types depending on the contents of uuid. The problem however is that the uuid contents will be autogenerated by the #import line, and so it won't be possible know ahead of time to know what to put in the typedef.
I also think that the $(InputName)_i.c file generated when building the COM component won't help because although it contains the correct GUID it won't be in the correct form for __uuidof
|
|
|
|
|
Try declaring a variable that (in some .cpp file) you'll define & initialise to the IID of the interface, like this:
class ITest ;
extern const IID ITest_IID;
_COM_SMARTPTR_TYPEDEF(ITest, ITest_IID);
That correctly forward declares ITestPtr so you can a) use a reference to it without needing the definition of ITest or ITest_IID , but b) can use the thing referred to once ITest and ITest_IID have been defined.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I get the error "redefinition; different basic types" when the #import defines the real thing.
|
|
|
|
|
You need to decouple things a bit more in that case. Here's an example that builds:
In the .h file:
class ITest ;
extern const IID ITest_IID;
_COM_SMARTPTR_TYPEDEF(ITest, ITest_IID);
In the .cpp file:
#import "libid:00020813-0000-0000-C000-000000000046" version("1.6") auto_search no_dual_interfaces rename("DialogBox", "excelDialogBox") rename("RGB", "excelRGB") rename("DocumentProperties", "excelDocumentProperties") rename("SearchPath", "excelSearchPath") rename("CopyFile", "excelCopyFile") rename("ReplaceText", "excelReplaceText")
class ITest : public Excel::_Application {};
const IID ITest_IID = __uuidof(Excel::_Application);
This defines a smart pointer, ITestPtr that wraps an Excel _Application pointer.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
It works up to a point, but the moment I introduce an accessor function to return a valid COM object the type ITest I get error C2027: use of undefined type 'ITest'
So:
HashImport.h
#pragma once
#include <comdef.h>
struct ITest;
extern const IID ITest_IID;
_COM_SMARTPTR_TYPEDEF(ITest, ITest_IID);
class CHashImport
{
public:
CHashImport();
~CHashImport();
HRESULT GetImpl(ITestPtr &pImpl);
};
</comdef.h>
HashImport.cpp
#include "StdAfx.h"
#include "Hashimport.h"
#import "libid:00020813-0000-0000-C000-000000000046" version("1.6") auto_search no_dual_interfaces rename("DialogBox", "excelDialogBox") rename("RGB", "excelRGB") rename("DocumentProperties", "excelDocumentProperties") rename("SearchPath", "excelSearchPath") rename("CopyFile", "excelCopyFile") rename("ReplaceText", "excelReplaceText")
struct ITest : public Excel::_Application {};
using namespace Excel;
const IID ITest_IID = __uuidof(Excel::_Application);
CHashImport::CHashImport()
{
ITestPtr ptr;
GetImpl(ptr);
}
CHashImport::~CHashImport()
{
}
HRESULT CHashImport::GetImpl(ITestPtr &pImpl)
{
pImpl = ITestPtr(__uuidof(Excel::Application));
_bstr_t appname = pImpl->GetValue();
return S_OK;
}
referenceheader.h
#pragma once
#include "hashimport.h"
class CReferenceHeader
{
public:
CReferenceHeader();
~CReferenceHeader();
};
referenceheader.cpp
#include "StdAfx.h"
#include "Referenceheader.h"
CReferenceHeader::CReferenceHeader()
{
}
CReferenceHeader::~CReferenceHeader()
{
}
main.cpp
#include "stdafx.h"
#include "hashimport.h"
#import "libid:00020813-0000-0000-C000-000000000046" version("1.6") auto_search no_dual_interfaces rename("DialogBox", "excelDialogBox") rename("RGB", "excelRGB") rename("DocumentProperties", "excelDocumentProperties") rename("SearchPath", "excelSearchPath") rename("CopyFile", "excelCopyFile") rename("ReplaceText", "excelReplaceText")
int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
CHashImport import;
::CoUninitialize();
return 0;
}
|
|
|
|
|
Yeah, that's because main.cpp needs a full definition of ITest or whatever the smart pointer class would be. You have no option at that point but to have a full definition of ITest.
Rename HashImport.h to HashImportFwd.h (like you have ios and iosfwd in the standard library).
Then create a new header called HashImport.h containing this:
#include "HashimportFwd.h"
#import "libid:00020813-0000-0000-C000-000000000046" version("1.6") auto_search no_dual_interfaces rename("DialogBox", "excelDialogBox") rename("RGB", "excelRGB") rename("DocumentProperties", "excelDocumentProperties") rename("SearchPath", "excelSearchPath") rename("CopyFile", "excelCopyFile") rename("ReplaceText", "excelReplaceText")
struct ITest : public Excel::_Application {};
Now, use HashImportFwd.h where the forward declaration is all that's needed and HashImport.h where you need the full definition.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Thanks for all your help Stuart
It's working fine!
I'm trying to come up with some macros to make it configurable, but the inability to redefine a #define as part of another #define doesn't seem to be possible.
|
|
|
|
|
Stone Free wrote: I'm trying to come up with some macros to make it configurable, but the inability to redefine a #define as part of another #define doesn't seem to be possible.
No, it's not - the pre-processor's not that clever (probably just as well, really)
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I created a ATL project with a modeless dialog. The ATL dll is called by a Delphi program. When the Delphi program invokes modeless dialog, it also creates a model dialog itself, so my modeless dialog in alt dell is insulated by the delphi model dialog in message sending.
|
|
|
|
|
That's nice.
Do you actually have a question?
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I have ATL web service Written in C++ long back.
We have already C++ web client using soap toolkit.
Now we need C++ web client Without Soap .
What are the solutions ?
Is it possible without .Net interface. That is it should work with old Vc++
6.0 IDE also.
|
|
|
|
|
ERLN wrote: Is it possible without .Net interface
Of course it is. If you're using MFC for the client (and MFC is a reasonable implementation route), then you probably want to get familiar with CHttpConnection [^] and CHttpFile [^].
Another route (which I used when writing a web service client in Haskell[^]) is to use libcurl[^] through its C++ bindings[^].
In both cases, you just need to construct an appropriate request, send it and read the response through the HTTP connection.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I have two vectors holding different classes. The first class contains only data of integer/double type. I can create a vector of the first class, access it, manipulate it, no problems.
The second class contains a combination of data and several pointers to allocated storage space. The space is allocated on the fly as needed. The destructor of the class frees the space. The problem arises when adding new instances of the class to the vector. If there isn't enough space in the vector, the vector class clones itself, adds space, and the erases the old vector. Unfortunately in erasing "old" vector, it frees the storage space and the program crashes because the storage pointers are invalid.
Creating a vector of pointers to the class solves the problem but would involve a massive re-write of code.
Anyone have any suggestions how to handle this? Is there a graceful way to handle pointers inside the class when you don't know when the class will be destroyed by the container?
|
|
|
|
|
Having a copy constructor for the second class should solve the problem.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
In addition to Superman's answer - you need to create an assignment operator that manages your memory as well.
Something like this:
class A
{
public:
A(int i) : pi_(new int(i)) {}
A(const A& a) : pi_(new int(*a.pi_)) {}
A& operator=(const A& a)
{
*pi_ = *a.pi_;
}
~A() { delete pi_; }
private:
int* pi_;
};
The other way round this is to manage your storage with (for example) Boost shared pointers[^].
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
When would the assignment operator be used?
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Any method that rearranges items in the vector. An example - the erase method (if you erase any except the last element).
Consider this example code:
#include <iostream>
#include <vector>
class Test
{
public:
Test() { std::cout << "Test::Test()\n"; }
Test( Test const& ) { std::cout << "Test::Test( Test const& )\n"; }
Test& operator=( Test const& ) { std::cout << "Test::operator=( Test const& )\n"; return *this; }
~Test() { std::cout << "Test::~Test()\n"; }
};
int main (int argc, char const* argv[])
{
std::vector<Test> a;
std::cout << "push_back\n";
a.push_back(Test());
a.push_back(Test());
a.push_back(Test());
std::cout << "iterator\n";
std::vector<Test>::iterator it = a.begin();
++it;
std::cout << "erase\n";
a.erase(it);
return 0;
}
It produces this output (with VS2008):
push_back
Test::Test()
Test::Test( Test const& )
Test::~Test()
Test::Test()
Test::Test( Test const& )
Test::Test( Test const& )
Test::~Test()
Test::~Test()
Test::Test()
Test::Test( Test const& )
Test::Test( Test const& )
Test::Test( Test const& )
Test::~Test()
Test::~Test()
Test::~Test()
iterator
erase
Test::operator=( Test const& )
Test::~Test()
Test::~Test()
Test::~Test()
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Wow, that explains a lot of the weird performance issues. Constructing large vectors (200-500) entries is what's taking up so much time. I am going with the vector of pointers because de-referencing them is fast compared to copying what can turn into very large classes. I am also reserving enough space so they won't constantly be copying themselves.
Thanks very much for the code example, it was very illuminating.
|
|
|
|
|
mjackson11 wrote: Constructing large vectors (200-500) entries is what's taking up so much time
Large? That's not large
I've tended to use vector s of Boost.SharedPointers[^] in the past, so I don't need to worry about deallocation (and also, it's easier to create indices into that vector, as you can just copy and re-sort the vector of smart pointers). That's been good for vectors with upwards of 10000 elements.
Another (and probably better) alternative would be a Boost pointer container[^].
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Thanks. That is new information.
So if I have 20 object stored in a vector and I delete the first, operator= is called 19 times!!!
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Yep - that's why rvalue references[^] are being introduced in C++0x - they allow the introduction of 'move semantics', which allows the elimination of unnecessary copies like that.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I had read about rvalue references and I'm able to admire it more now.
Thanks
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Hello friend,
I need to show one small "Please Wait.." image screen whenewer some back end processing is in progress.
For e.g. whenever user changing his ip adress and port, before going checking and establishing the connection, I want to show a "Please wait ..." image.But while going for connection browser gets hangs because of connection and after connection checking is completed. It goes for next page.
I am using IWebBrowser2 interface through which, I am getting pointer of browser.Then I am using IHTMLELement through which I am getting pointer of current html content.After that I am using IHTMLImageElement to add one img tag inside current html page for please wait screen.
Please give me some suggestions.
Waiting for the positive reply
Thank you.
abhi
|
|
|
|