?
Solved

How to export a interface (or object) from one application to another ?

Posted on 2006-05-04
12
Medium Priority
?
581 Views
Last Modified: 2010-08-05
How to export a interface (or object) from one application to another ?

I have some code below of how i think it should work..  but it doesn't work :(

Can anyone point me in the right direction and/or provide me with some sourcecode that helps me figure out how to get this working ?

  ITest = interface(IUnknown)
    ['{9C0CBC60-78CD-494F-8C71-B8FA1CD8459C}']
    Procedure TestProc;stdcall;
  End;

  TTest = class(TInterfacedObject,ITest)
    Procedure TestProc;stdcall;
  End;

  TApp1Form1= class(TForm)
  public
    Test:TTest;
    MyITest:ITest;
    MyMsgResp,
    MyMsg:Cardinal;
  End;

procedure TApp1Form1.FormCreate(Sender: TObject);
begin
  Test:=TTest.create;
  Test._AddRef;
  MyMsg := RegisterWindowMessage('requestinterface');
  MyMsgResp := RegisterWindowMessage('requestinterface_Resp');
  Application.OnMessage := AppMessage;
end;

procedure TApp1Form1.AppMessage(var Msg: TMsg; var Handled: Boolean);
Var
  LP:Integer;
begin
  if Msg.Message = MyMsg then
  begin
    Test.QueryInterface(ITest,MyITest);
    LP:=Integer(MyITest);
    PostMessage(Msg.wParam,MyMsgResp,123,LP);//POST THE INTERFACE
    Handled := true;
  end;
end;
-------------------------------------------------------------------------

procedure TApp2Form2.FormCreate(Sender: TObject);
begin
  MyMsg := RegisterWindowMessage('requestinterface');
  MyMsgResp := RegisterWindowMessage('requestinterface_Resp');
  Application.OnMessage:=AppMessage;
end;

procedure TApp2Form2.ButtonGetObjectClick(Sender: TObject);
begin
  PostMessage(HWND_BROADCAST,MyMsg,Application.Handle,0); //REQUEST THE INTERFACE
end;

procedure TApp2Form2.AppMessage(var Msg: TMsg; var Handled: Boolean);
Var
  T:ITest;
  LP:Integer;
  IU:IUnknown;
begin
  if Msg.Message = MyMsgResp then
  begin
    LP:=msg.lParam;  //RECIEVE THE INTERFACE
    TestIF:=ITest(LP); //THIS IS WHERE MY APP CRASHES
    If TestIF <> nil Then
    Begin
      ShowMessage('Supports ITest');
      If Assigned(TestIF) Then
      Begin
        TestIF.TestProc; //AND THEN USE IT
      End;
    End else
      ShowMessage('NOT Supports ITest');
  end;
end;
0
Comment
Question by:piba
  • 8
  • 4
12 Comments
 
LVL 34

Expert Comment

by:Slick812
ID: 16617253
hello piba, ,  First, I'll try and say why your code crashes, , You do not seem to realize that the windows system sets up "Separate" memory space for Different Instances (Programs),, when you use the code -
   PostMessage(Msg.wParam,MyMsgResp,123,LP);

the LP is a Memory address in your Instance, so when you try the -
    TestIF:=ITest(LP); //THIS IS WHERE MY APP CRASHES

the other program DOES NOT have access to the first program's memory address of  LP , , so you get a system AV and crash

As far as I have ever seen, to have an "Inteface" that is "Shared" between two programs, you may have to use  COM, but I do not think (from what I understand of your comments) that you will want the COM type of interprocess link.

It seems to me that you might can accomplish some or all of what you need  by using the system SendMessage or PostMessage functions.
Have you considered that?
0
 
LVL 3

Author Comment

by:piba
ID: 16621211
Thanks for your comment Slick,

I understand why i get the crash .. is there any way to make the interface available for both program's ?

I dont want to use COM

I suppose it could be done with messages only .. but i like the idee of being able to use an interface more. Becouse i think it would than be much easyer to have several functions that can be called from another application and return some values.
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 2000 total points
ID: 16622486
OK, I was not really sure about an Interface (based in IUnknown) that is defined and created in a program as your -
 ITest = interface(IUnknown)
was some how also connected to the windows system, for example,  the ITest GUID was in the "System" as a reference to the ITest, , I have done some research on this, and all that I was able to read about it seems to indicate to me that there is NO system information added about the ITest interface when you create it, the only information about the ITest that the system has is for the defaullt attributes for IUnknown. As near as I can understand, when you create an Interface or Object (ITest or TTest) ALL of the memory used for this is in that process, and is NOT shared memory, even though it may be an Interface. . So, I found in some references, that to to get interprocess linking (as in call a function in another process) using interfaces,  uses the IMarshall interface to set up a way to exchange (send, receive) info, since the two processes do NOT access each others memory, the IMarshall (used with the IDispatch) sets up a way to pass (send, marshall) the memory blocks for parameters and result to the function of another process (not as simple as this sounds, apparently). From all indications (as I see them in the info), To use the IDispatch or IMarshall requires that the GUID of the Interface be "Registered" in the system as a COM server (have a DLL or program with a TLB) so the system can know what functions the Interface supports and where the function memory blocks (code) to implement the functions is located, the DLL or program. So, it seems that  just because it is an Interface, it does not make it assesible memory to other processes.

I can Not say that it is not possible to link processes with out the interface GUID being registerd? It may be possible with -
  CoMarshalInterThreadInterfaceInStream(  )
to use the IUnknown as your base Interface and define your own stream for data transfer, but I could NOT find any code for this, all the code used parameters  registered interface GUID,  I have never done any thing with custom marshallers, so I am just guessing, , sorry this subject is  very complex for me and I am just trying to give you some ideas about it. . But I know that (for NON Interface)  trying to get, use or function in another process memory space is difficult, and I have learned not to even try that if I can avoid it.

As I said, I would use the SendMessage and PostMessage for interprocess functioning, this avoids memory access violation and thread sync problems
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 3

Author Comment

by:piba
ID: 16625513
Thanks for trying to help me find an anser Slick :)

I think its gooing in the right direction.. but still get an EOleSysError

  ITest = interface(IInterface)
    ['{9C0CBC60-78CD-494F-8C71-B8FA1CD8459C}']
    Procedure TestProc;stdcall;
  End;

  TTest = class(TInterfacedObject,ITest)
    Procedure TestProc;stdcall;
  End;

procedure TTest.TestProc;
begin
   ShowMessage('Test message');
end;

procedure TApp1Form1.Button1Click(Sender: TObject);
Var
  Test:TTest;
  MyITest:ITest;
  T:int64;
  FStream: IStream;
  hGlob:Cardinal;

  FStream2:IStream;
  hGlob2:Cardinal;
  MyITest2:ITest;
begin
  Test:=TTest.create;
  Test._AddRef;
  Test.QueryInterface(ITest,MyITest);

  MyITest.TestProc;

  OleCheck(CreateStreamOnHGlobal(0, False, FStream));
  Try
    OleCheck(CoMarshalInterThreadInterfaceInStream(ITest,IUnknown(MyITest),FStream)); // EOleSysError 'interface not registered' (translated from my OS language)
  Except
    OleCheck(CoMarshalInterface(FStream,ITest,IUnknown(MyITest),MSHCTX_NOSHAREDMEM, nil, MSHLFLAGS_NORMAL)); // EOleSysError 'interface not registered' (translated from my OS language)
  End;
  OleCheck(GetHGlobalFromStream(FStream, hGlob));

  hGlob2:=hGlob;  // hGlob is going to be posted from one application to the other

  OleCheck(CreateStreamOnHGlobal(hGlob2, False, FStream2));
  OleCheck(CoUnmarshalInterface(FStream2,ITest,IUnknown(MyITest2)));
  MyITest2.TestProc;

  FStream:=nil;
end;
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16626001
All I can say is that it looks like  ALL system marshalling (IMarshall) will require a registered interface (in other words it needs a properties reference (TLB) and a memory block (executable, DLL, EXE) for code) for the COM functions to work.
0
 
LVL 3

Author Comment

by:piba
ID: 16627251
Its working partialy now .. I can call the interface but then a few line after that i get an AV.

Im am now using a FileMapping to send the marchalled data to the other application. And it seems to be working ..

Im not sure if this is becoming a COM object or not but my understanding of COM was that it was always requiered to register the interfaces with regsvr32 or something and that is the part i dont want.

here is what i have got at this moment.. qould you help me find a solution for the AV i am still getting ?

unit Project1_TLB;

// ************************************************************************ //
// WARNING                                                                    
// -------                                                                    
// The types declared in this file were generated from data read from a      
// Type Library. If this type library is explicitly or indirectly (via        
// another type library referring to this type library) re-imported, or the  
// 'Refresh' command of the Type Library Editor activated while editing the  
// Type Library, the contents of this file will be regenerated and all        
// manual modifications will be lost.                                        
// ************************************************************************ //

// PASTLWTR : 1.2
// File generated on 8-5-2006 2:15:51 from Type Library described below.

// ************************************************************************  //
// Type Lib: E:\Project1.tlb (1)
// LIBID: {B4AE710E-DBB8-4982-A455-0E713F5A7DD3}
// LCID: 0
// Helpfile:
// HelpString: Project1 Library
// DepndLst:
//   (1) v2.0 stdole, (C:\WINDOWS\system32\stdole2.tlb)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
 

// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:        
//   Type Libraries     : LIBID_xxxx                                      
//   CoClasses          : CLASS_xxxx                                      
//   DISPInterfaces     : DIID_xxxx                                      
//   Non-DISP interfaces: IID_xxxx                                        
// *********************************************************************//
const
  // TypeLibrary Major and minor versions
  Project1MajorVersion = 1;
  Project1MinorVersion = 0;

  LIBID_Project1: TGUID = '{B4AE710E-DBB8-4982-A455-0E713F5A7DD3}';

  IID_ITestInterface: TGUID = '{6EA533AB-BE1A-4EF6-B5AA-E9397E9F2E10}';
  CLASS_TestInterface: TGUID = '{61194454-6B06-408F-A37F-EA16EBE27016}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary                    
// *********************************************************************//
  ITestInterface = interface;
  ITestInterfaceDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library                      
// (NOTE: Here we map each CoClass to its Default Interface)              
// *********************************************************************//
  TestInterface = ITestInterface;


// *********************************************************************//
// Interface: ITestInterface
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {6EA533AB-BE1A-4EF6-B5AA-E9397E9F2E10}
// *********************************************************************//
  ITestInterface = interface(IDispatch)
    ['{6EA533AB-BE1A-4EF6-B5AA-E9397E9F2E10}']
    procedure TestProc(val: Integer); safecall;
  end;

// *********************************************************************//
// DispIntf:  ITestInterfaceDisp
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {6EA533AB-BE1A-4EF6-B5AA-E9397E9F2E10}
// *********************************************************************//
  ITestInterfaceDisp = dispinterface
    ['{6EA533AB-BE1A-4EF6-B5AA-E9397E9F2E10}']
    procedure TestProc(val: Integer); dispid 201;
  end;

// *********************************************************************//
// The Class CoTestInterface provides a Create and CreateRemote method to          
// create instances of the default interface ITestInterface exposed by              
// the CoClass TestInterface. The functions are intended to be used by            
// clients wishing to automate the CoClass objects exposed by the        
// server of this typelibrary.                                            
// *********************************************************************//
  CoTestInterface = class
    class function Create: ITestInterface;
    class function CreateRemote(const MachineName: string): ITestInterface;
  end;

implementation

uses ComObj;

class function CoTestInterface.Create: ITestInterface;
begin
  Result := CreateComObject(CLASS_TestInterface) as ITestInterface;
end;

class function CoTestInterface.CreateRemote(const MachineName: string): ITestInterface;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_TestInterface) as ITestInterface;
end;

end.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActiveX, ComObj, StdCtrls, OleCtrls, InvokeRegistry, Project1_TLB,
  Unit4,USharedMem,

ComServ;

Const
  CLASS_Test: TGUID = '{72B653D0-2AD0-44F0-943F-F6C7B5E7B34A}';
type
(*  ITest = interface(IDispatch)
    ['{9C0CBC60-78CD-494F-8C71-B8FA1CD8459C}']
    Procedure TestProc;safecall;
  End;
  ITestDisp = dispinterface
    ['{D0BC8553-1D1B-4955-A319-2F9C1A0DB4D8}']
    procedure TestProc; dispid 201;
  end;
*)
(*  TTest = class(TAutoObject,IPBAutomation)
    Procedure TestProc2;safecall;

    {function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; virtual; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; virtual; stdcall;
    function GetTypeInfoCount(out Count: Integer): HResult; virtual; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; virtual; stdcall;}
  End;*)

  TApp1Form1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
  private
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
    { Private declarations }
  public
    { Public declarations }
    TestObject:TTestInterface;
    MyMsgResp,
    MyMsg:Cardinal;
  end;

var
  App1Form1: TApp1Form1;

implementation

{$R *.dfm}

procedure TApp1Form1.FormCreate(Sender: TObject);
begin
  TestObject:=TTestInterface.Create;

  MyMsg := RegisterWindowMessage('requestinterface');
  MyMsgResp := RegisterWindowMessage('requestinterface_Resp');
  Application.OnMessage := AppMessage;
end;

procedure TApp1Form1.AppMessage(var Msg: TMsg; var Handled: Boolean);
Var
  hGlob:Cardinal;
  FStream: IStream;
  MyITest:ITestInterface;
  MyPLong:PLongint;
  StreamData:String;
  B:Byte;
  MyI64:Int64;
  SM:TSharedMem;
begin
  if Msg.Message = MyMsg then
  begin
    MyITest:=TestObject;
    OleCheck(CreateStreamOnHGlobal(0, False, FStream));
   
    OleCheck(CoMarshalInterface(FStream,ITestInterface,IUnknown(MyITest),MSHCTX_NOSHAREDMEM, nil, MSHLFLAGS_NORMAL)); // EOleSysError 'interface not registered' (translated from my OS language)
    OleCheck(GetHGlobalFromStream(FStream, hGlob));
    SM:=TSharedMem.create('InterfaceSharingTest',68,False);

    new(MyPLong);
    FStream.Seek(0,0,MyI64);
    StreamData:='';
    While Succeeded(FStream.Read(@B,1,MyPLong)) and (MyPLong^ > 0) Do
    Begin
      StreamData:=StreamData+Chr(B);
    End;
    Dispose(MyPLong);
    Move(StreamData[1], SM.Buffer^, Length(StreamData));

    {POST A REPLY THAT THE SHARED MEMORY IS
      FILLED WITH THE MARCHAL INTERFACE STREAM}
    PostMessage(Msg.wParam,MyMsgResp,0,0);
    Handled := true;
  end;
end;

initialization
end.

unit Unit4;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  ComObj, ActiveX, Project1_TLB, StdVcl, Dialogs, Sysutils;

type
  TTestInterface = class(TAutoObject, ITestInterface)
  protected
    procedure TestProc(val: Integer); safecall;
  end;

implementation

uses ComServ;

{$R MyInterface.tlb}

procedure TTestInterface.TestProc(val: Integer);
begin
  showmessage('TTestInterface.TestProc val:'+Inttostr(val));
end;

initialization
  TAutoObjectFactory.Create(ComServer, TTestInterface, Class_TestInterface,
    ciMultiInstance, tmNeutral);
end.

unit USharedMem;

interface

uses Windows;
Type
  THandledObject = class(TObject)
  protected
    FHandle: THandle;
  public
    destructor Destroy; override;
    property Handle: THandle read FHandle;
  end;

  TSharedMem = class(THandledObject)
  private
    FName: string;
    FSize: Integer;
    FCreated: Boolean;
    FFileView: Pointer;
  public
    constructor Create(const Name: string; Size: Integer;Open:Boolean);
    destructor Destroy; override;
    property Name: string read FName;
    property Size: Integer read FSize;
    property Buffer: Pointer read FFileView;
    property Created: Boolean read FCreated;
  end;

implementation

uses Messages, Classes, Sysutils;

{ THandledObject }

destructor THandledObject.Destroy;
begin
  if FHandle <> 0 then
    CloseHandle(FHandle);
end;

procedure Error(const Msg: string);
begin
  raise Exception.Create(Msg);
end;

{ TSharedMem }

constructor TSharedMem.Create(const Name: string; Size: Integer;Open:Boolean);
begin
  try
    FName := Name;
    FSize := Size;
    { CreateFileMapping, when called with $FFFFFFFF for the handle value,
      creates a region of shared memory }

    If Open Then
      FHandle:=OpenFileMapping(FILE_MAP_READ, // access mode
        false, // inherit flag
        pchar(Name))
    Else
    If FHandle = 0 Then
      FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
        Size, PChar(Name));

    if FHandle = 0 then abort;
    FCreated := GetLastError = 0;
    { We still need to map a pointer to the handle of the shared memory region
}
    If Open Then
      FFileView := MapViewOfFile(FHandle, FILE_SHARE_READ, 0, 0, Size)
    Else
      FFileView := MapViewOfFile(FHandle, FILE_SHARE_WRITE, 0, 0, Size);
     
    if FFileView = nil then abort;
  except
    Error(Format('Error creating shared memory %s (%d)', [Name,
      GetLastError]));
  end;
end;

destructor TSharedMem.Destroy;
begin
  if FFileView <> nil then
    UnmapViewOfFile(FFileView);
  inherited Destroy;
end;

end.


unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ActiveX, ComObj, Project1_TLB, USharedMem;

type
  ITest = interface(IUnknown)
    ['{9C0CBC60-78CD-494F-8C71-B8FA1CD8459C}']
    Procedure TestProc;stdcall;
  End;

  TApp2Form2 = class(TForm)
    ButtonGetObject: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ButtonGetObjectClick(Sender: TObject);
  private
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
    { Private declarations }
  public
    { Public declarations }
    MyITest:ITest;
    MyMsgResp,
    MyMsg:Cardinal;
  end;

var
  App2Form2: TApp2Form2;

implementation

{$R *.dfm}

Procedure GetHGlobSize(hglob:Cardinal);
Var
  FStream2:IStream;
  MyI64:Int64;
  X:Integer;
  MyPLong:PLongint;
  Dummy:Byte;
Begin
  OleCheck(CreateStreamOnHGlobal(hglob, False, FStream2));
  FStream2.Seek(0,0,MyI64);
  X:=0;
  New(MyPLong);
  While Succeeded(FStream2.Read(@Dummy,1,MyPLong)) and (MyPLong^ > 0) Do inc(X);
  ShowMessage('HGlob size:'+IntToStr(MyPLong^)+ '  '+inttostr(X));
  Dispose(MyPLong);
End;

procedure TApp2Form2.FormCreate(Sender: TObject);
begin
  MyMsg := RegisterWindowMessage('requestinterface');
  MyMsgResp := RegisterWindowMessage('requestinterface_Resp');
  Application.OnMessage:=AppMessage;
end;

procedure TApp2Form2.ButtonGetObjectClick(Sender: TObject);
begin
  PostMessage(HWND_BROADCAST,MyMsg,Application.Handle,0); //REQUEST THE INTERFACE
end;

procedure TApp2Form2.AppMessage(var Msg: TMsg; var Handled: Boolean);
Var
  TestIF:ITestInterface;
  FStream:IStream;
  MyPLong:PLongint;
  MyI64:iNT64;
  SM:TSharedMem;
begin
  if Msg.Message = MyMsgResp then
  begin
    SM:=TSharedMem.create('InterfaceSharingTest',68,True);
    OleCheck(CreateStreamOnHGlobal(0, False, FStream));
    New(MyPLong);
    FStream.SetSize(68);
    FStream.Write(SM.Buffer,68,MyPLong);
    FStream.Seek(0,0,MyI64);
    Dispose(MyPLong);

    OleCheck(CoGetInterfaceAndReleaseStream(FStream,ITestInterface,TestIF));
    ShowMessage('Test1');
    TestIF.TestProc(101); //AND THEN USE IT
    ShowMessage('Test2');
    TestIF.TestProc(2004); //AND THEN USE IT
    ShowMessage('Interface calls complete');

    TestIF:=nil;
    FreeAndNil(SM);
    ShowMessage('Done');
    //after this message "Access violation at address 00700072 Read of address 00700072"
  end;
end;

end.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16633665
???
I have looked at your code above, and gone through each unit code, ,
you say -
" COM was that it was always requiered to register the interfaces with regsvr32 "
This is True, however, in your unit4 code you have -

initialization
  TAutoObjectFactory.Create(ComServer, TTestInterface, Class_TestInterface,
    ciMultiInstance, tmNeutral);

It is my understanding (but I do not have time now to look up the code and assorted function references) that when you use the Delphi COM creation stuff like TAutoObjectFactory  , , that in an Executable it will automatically register your com server with the system, so even though you do not directly call the  regsvr32   to register, it is auto called by code in comserver.pas each time the exe runs, , as I see your code you have a registered COM server in your Unit1 program (.exe) which uses unit4. . . .  So your efforts in unit2 for a COM connection can be done with more normal delphi COM methods, since your contact program is a com server, , but I may be mistaken, since I did not run your code.

I am not to sure about your access violation in unit2, however, I suspect that you dump the Shared memory to soon, , I would think that the IDispatch will do some disconect and cleanup after the -
procedure TApp2Form2.AppMessage(var Msg: TMsg; var Handled: Boolean);
has finished processing, ?,
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16636436
I spent some more time looking at your code, and trying to see what it was doing, , , I do not beleive that your methods ever marshal anything across the processes, , It looks to me that you copy the memory used for the ITestInterface implementation that you get with the CoMarshalInterface(  ) into an IStream, this IStream is coppied to the Mem Map shared memory,  In the other process you create an IStream and copy the shared mem map memory to the IStream, and then initialize the TestIF interface with CoGetInterfaceAndReleaseStream, , but this IStream  is local in that process memory, not marshalled from another process, , I tried to find something about doing an IMarshall transfer, but have not found but a few references, ,it seems that the  IBindCtx  interface is involved some way, there seems to be a "RunningObjectTable" that is used to store the data (memory or memory access info) that is used for marshaling, having shared memory in it it seems. .  I beleive that the IMarshal::MarshalInterface may be used?, ,most of the references I have read so far say to let the system do all of the com work for marshalling since it has so many thing to consider, , I am sorry I do not have much free time now, , but it seems like this would require mush time to research and implement
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16636487
There are also the CoMarshalInterface and the CoUnmarshalInterface functions, but I have not used them
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16636502
I probally should not give any more untested comments, since this seems to be likely to be as un-helpful as helpful
0
 
LVL 3

Author Comment

by:piba
ID: 16643673
Hi Slick,

Thanks for all the time you spend, and though things did not exactly turn out the way, i initialy thought, i wanted i am happy with the result.

I will give you the points with an A if thats ok by you.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16645288
Yea its OK, , but i will complain some about MS and their backed-up mess that they invented for the common object model COM, , I have many times tried to use the various interfaces that windows system has, and they are frustrating to try and read about and figure out and then work some code that has any succesful results. . . Although by now I have some knowledge for this interface stuff, it is still a mess to try and implement, even if you have a working example of code to run, and then try and modify it to get something that you actually need to use. I would think you can see this from your work with this question? I know that the interface implementation was designed to be portable (more than one version of windows) and upgradeable (requiring some crap complexities), , but as an "Object" programming for developers it is a  system that does not really offer much "Object" transportation, a bad setup (my opinion).

some of my thoughts on this question, , I do not feel that it would be worth while (time and effort) to try and implement an interface as you have described, without a COM server, , but I feel that if I could get an IMoniker and then place some of the nessary memory in an IStream and set up an IRunningObjectTable entry with the IMoniker (the GUID I think) and then retrive the IStream from the IRunningObjectTable in the other process, , but if the interface is not registered, I beleive you would need some complex code to get the Interface from the IStream in the other process. . .

Good luck, you may do a net search for doing a "custom marshalling"
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question