Implementation of interface in .NET COM client does not work

I have made a .NET COM client app using Delphi Prism (Oxygene version is 4.0.25) with .NET 4.0. Everything works fine except one class method. One of method’s parameters takes an IStream interface. The routine also requires the use of SHCreateStreamOnFile.

In the interface section I import the win32 API:

type     
  Win32Methods = class
  public    
    [DllImport('shlwapi.dll', CharSet := CharSet.Unicode, CallingConvention := CallingConvention.StdCall, 
      EntryPoint := 'SHCreateStreamOnFileW')] 
     class method SHCreateStreamOnFileW(pszFile: String; grfMode: UInt32;
        ppstm: System.Runtime.InteropServices.ComTypes.IStream): System.Int32; external;    
  end;

Then in the implementation section in a buttonclick procedure:

var
  FileIStream: System.Runtime.InteropServices.ComTypes.IStream;
begin

  FileIStream := nil;   

  FilePath := a file path;         
      
  Win32Methods.SHCreateStreamOnFileW(FilePath, STGM_READ OR STGM_SHARE_DENY_WRITE, FileIStream);
      
  MyClass.AddFile(FilePath, FileIStream);

It throws an exception but gives no information as to why it failed.
I’ve tried the non-W version of SHCreateStreamOnFile, commenting out FileIStream := nil and
a few other things but none fixed the problem. How do you implement an interface in Oxygene?

bilm

You probably want something like:

type
[DllImport('shlwapi.dll', CharSet := CharSet.Unicode, CallingConvention := CallingConvention.StdCall, 
      EntryPoint := 'SHCreateStreamOnFileW')] 
     class method SHCreateStreamOnFileW(pszFile: String; grfMode: UInt32;
        var ppstm: System.Runtime.InteropServices.ComTypes.IStream): System.Int32; external;  
  end;

So the stream is properly returned in FileIStream

I’m sure there are other implementations that will work including yours. But I happened to find one before I saw your post. This is what works for me.

type
Win32Methods = public static class
private
protected
public
[DllImport(‘shlwapi.dll’, CharSet := CharSet.Unicode, CallingConvention := CallingConvention.StdCall,
ExactSpelling := True, PreserveSig := False, EntryPoint := ‘SHCreateStreamOnFileW’)]
class method SHCreateStreamOnFileW(pszFile: String; grfMode: UInt32;
out ppstm: System.Runtime.InteropServices.ComTypes.IStream): System.Int32; external;
end;

// then call
Win32Methods.SHCreateStreamOnFileW(‘full path of file’, STGM_READ OR STGM_SHARE_DENY_WRITE, MyInstream);