title: How to call .NET from Delphi?
body: <h2>THIS IS NOT A DUPLICATE</h2>
  
  <p><strong>Duplicate marking note above ^ is wrong.</strong></p>
  
  <p>How can one invoke parametrised methods of a .NET library (not a registered COM object) from a Delphi 2010 program?</p>
  
  <p>Specifically, I would like to access the Saxon API, as documented <a href="http://www.saxonica.com/documentation/dotnetdoc/index.html" rel="nofollow noreferrer">here</a>. Specifically, I can create an XsltCompiler and read the BaseURI property, but not set it.</p>
  
  <p>I have had some success using Win32 COM Server Objects (mscoree.dll and mscorlib.dll) and Late Binding. This is thanks to the example of the Project-Jedi TJclClrHost component. I can load .NET assemblies, create .NET objects and read simple string properties or functions without parameters. My question is how to pass parameters?</p>
  
  <p>This question is exemplified by the task of how to set the Base URI of an XsltCompiler loaded from the Saxon .NET assembly. The API for BaseUri is documented <a href="http://www.saxonica.com/documentation/dotnetdoc/Saxon/Api/XsltCompiler.html#BaseUri" rel="nofollow noreferrer">here</a> , the salient part of which is ...</p>
  
  <pre><code>public Uri BaseUri {get; set; }
  </code></pre>
  
  <p>Using reflection, I have determined that the name of the setter function is 'set_BaseUri'.</p>
  
  <p>This method can be called using Late Binding/ Reflection from the type library imported from <code>mscorlib.dll</code>. The relevant method is listed below.</p>
  
  <pre><code>_Type = interface(IDispatch)
    ['{BCA8B44D-AAD6-3A86-8AB7-03349F4F2DA2}']
  ....
    function InvokeMember(const name: WideString; invokeAttr: BindingFlags; const Binder: _Binder; 
                        Target: OleVariant; args: PSafeArray; modifiers: PSafeArray; 
                        const culture: _CultureInfo; namedParameters: PSafeArray): OleVariant; safecall;
  ...
  end;
  </code></pre>
  
  <h1>What I have tried so far?</h1>
  
  <p>In my Delphi 2010 program, I write ..</p>
  
  <pre><code>FType.InvokeMember( 'set_BaseUri',
    BindingFlags_Public or BindingFlags_Instance or BindingFlags_InvokeMethod or
    BindingFlags_SetField or BindingFlags_SetProperty,
    nil, FInstance, args, modifiers, nil, nil);
  </code></pre>
  
  <p>where:
    <code>FType</code> is of type <code>_Type</code>.
    <code>args</code> and <code>modifiers</code> are both a PSafeArray of length 1. modifiers is supposed to be an array of booleans to say if the argument is pass by reference or pass by value. In our case, this is an array of one boolean with a value of False (pass by value). args is supposed to be the array of actual parameter values.</p>
  
  <p>I have tried all sorts of array element types, but I keep getting an error 'Specified array was not of the expected type.'</p>
  
  <p>This is my code to set the args safeArray to some string.</p>
  
  <pre><code>var
    args: PSafeArray;
    argsbound: TSafeArrayBound;
    PassByRef: boolean;
    Idx: integer;
    OValue: OleVariant;
  begin
  Idx := 0;
  argsbound.cElements := 1;
  argsbound.lLbound   := 0;
  args := SafeArrayCreate( VT_VARIANT, 1, argsbound);
  OValue := 'www.abc.net.au';
  SafeArrayPutElement( args, Idx, OValue);
  ...
  </code></pre>
  
  <h1>Avenues that I have looked into, but are not solutions</h1>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/2048540">Hosting CLR in Delphi with/without JCL - example</a></li>
  <li><a href="http://www.blong.com/Conferences/BorConUK2002/Interop2/COMNetInterop.htm" rel="nofollow noreferrer">http://www.blong.com/Conferences/BorConUK2002/Interop2/COMNetInterop.htm</a></li>
  </ul>
  
  <h2>THIS IS NOT A DUPLICATE</h2>
  
  <p>ChrisF was wrong to mark this as a <a href="https://stackoverflow.com/questions/6174584">duplicate</a> . The referenced question and answers refer only to situations where the developer controls and writes the .Net assembly. As stated, the assembly attempting to be invoked is a third party (Saxon). The question has been satisfactorily answered, but it should not have been closed as a duplicate.</p>