tags:

views:

41

answers:

2

What I am trying to do is transfer an object that has been created on the serverside to the client. I have got it to work well when I using c++ on both server and client side, but I do not get my server to work correct with other languages like .Net, It probably doesn't like the pointers!

Does this Serversidecode look correct?

Server Form: .h

class TForm2 : public TForm
{
__published:      // IDE-managed Components
      TMemo *Memo1;
private:      // User declarations
      DummyComObj* formDummy;
public:            // User declarations
      __fastcall TForm2(TComponent* Owner);
      IDummyComObj* Getformdummy();
};

.cpp

__fastcall TForm2::TForm2(TComponent* Owner)
      : TForm(Owner)
{
      CoCreateInstance( CLSID_DummyComObj,NULL,CLSCTX_ALL,IID_IDummyComObj,(void**)&formDummy);
}

DummyComObj* TForm2::Getformdummy()
{
      return formDummy;
}

Server TestComServerImpl: .cpp

STDMETHODIMP STDMETHODCALLTYPE TServerDidleComTestImpl::GetMyObject(IDummyComObj** outObj)
{
      DummyComObj *myDum = Form2->Getformdummy();
      *outObj = &myDum;
      return S_OK;
}
+1  A: 

Your GetMyObject() method is bad, it returns a pointer to a local variable. That will only work by accident, never for any language that wraps COM. Fix (minus error handling):

DummyComObj *myDum = Form2->Getformdummy();
return myDum->QueryInterface(__uuidof(IDummyComObj), outObj);

Not sure if __uuidof() is available in Builder, use whatever you got to get the IID of the interface.

Hans Passant
Strictly speaking you should check if QI() succeeded. If it fails AddRef() has not been called and you have to release the object (delete in C++) prior to returning, otherwise the object will have been leaked.
sharptooth
Hmya, I figured the "minus error handling" stipulation in my post wasn't enough to keep comments at bay. It isn't at all clear what the proper error handling should look like from the OP's snippets.
Hans Passant
But what about the IDummyComObj** outObj Parameter in GetMyObjectwhen I try to import this typelib to a .Net client it does not recognize this and do not import this method.
Qwark
That's an entirely different question, maybe you ought to start another thread about it. Is the interface declared in the type lib? Use Oleview.exe, File + View Type Library.
Hans Passant
Yes the IDummmyComObj is declared in the typelib and it is only the methods that have pointers as parameters/return values that are not imported.I will make a new question about this.
Qwark
+1  A: 

Asside from TServerDidleComTestImpl::GetMyObject() not compiling due to you trying to assign a DummyComObj ** to a DummyComObj*, but you are also completely ignoring COM reference counting rules.

Try this instead:

Server Form: .h

#include <utilcls.h>

class TForm2 : public TForm
{
__published: // IDE-managed Components
    TMemo *Memo1;
private: // User declarations
    TComInterface<IDummyComObj> formDummy;
public: // User declarations
    __fastcall TForm2(TComponent* Owner);
    void Getformdummy(IDummyComObj** outObj);
};

Server Form: .cpp

__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
    CoCreateInstance( 
CLSID_DummyComObj,NULL,CLSCTX_ALL,IID_IDummyComObj,(void**)&formDummy);
}

HRESULT TForm2::Getformdummy(DummyComObj** outObj)
{
    return formDummy->QueryInterface(IID_IDummyComObj,(void**)outObj);
}

Server TestComServerImpl: .cpp

STDMETHODIMP STDMETHODCALLTYPE 
TServerDidleComTestImpl::GetMyObject(IDummyComObj** outObj)
{
    return Form2->Getformdummy(outObj);
}
Remy Lebeau - TeamB