Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The first issue I see is that Delphi's binary interface for function return values is different from that used by C# (and indeed every other major Windows compiler).</p> <p>So instead of using a function, use an <code>out</code> parameter.</p> <pre><code>procedure CreateMyDate(out Date: IMyDate); stdcall; begin Date := TMyDate.Create; end; </code></pre> <p>Then on the C# you can declare the function like this:</p> <pre><code>[DllImport(@"Project11.dll")] public static extern void CreateMyDate(out IMyDate Date); </code></pre> <p>Note that I removed a load of spurious parameters to your <code>DllImport</code> attribute. I guess you were adding them at random!</p> <p>The other issue is the interface. It needs to be declared as being a COM interface that supports <code>IUnknown</code>. Like this:</p> <pre><code>[ComImport, Guid("D032F796-167D-4B0D-851D-2AEEA226646A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMyDate { void Analyze_Date(ref int y, int m, int d); } </code></pre> <p><strong>Update 1</strong></p> <p>The first problem with the updated question is something I failed to pick up in my original answer. The way the C# interface is declared means that that the marshaller assumes that the native functions all return <code>HRESULT</code> COM error codes. If the C# method has a return value then it is implicitly converted into an <code>out</code> parameter. There is a simple way to achieve this in Delphi. You replace <code>stdcall</code> with <code>safecall</code> on each method in the interface, and obviously in the implementation of that interface. Note that you should not change the calling convention of the <code>CreateMyDate</code> function.</p> <p>So your Delphi code should be like this:</p> <pre><code>IMyDate = interface ['{D032F796-167D-4B0D-851D-2AEEA226646A}'] Function testing():Boolean; safecall; end; TMyDate = Class(TInterfacedObject, IMyDate) Public Function testing():Boolean; safecall; End; </code></pre> <p>Another problem with the method in updated question is that C# marshals <code>bool</code> as a 4 byte value, but Delphi <code>Boolean</code> is just a single byte. This error is actually benign, but you can fix the problem by making the two sides of the interface match. For example:</p> <pre><code>[return: MarshalAs(UnmanagedType.U1)] bool testing(); </code></pre> <p>And I repeat what I said above. I removed spurious parameters from your <code>DllImport</code> attribute. In particular don't use <code>SetLastError</code> because your code is not setting the Win32 last error. Your <code>DllImport</code> should be exactly as per my answer. Don't confuse things by adding needless extra parameters to the attribute.</p> <p><strong>Update 2</strong></p> <p>You say in comments that you can't use <code>safecall</code> on the Delphi side. Which means that you need to suppress the <code>HRESULT</code> signature transformation on the C# side of the interface. That's done with <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.preservesigattribute.aspx" rel="nofollow"><code>MethodImplOptions.PreserveSig</code></a>. You need to apply it to each method on your C# interface.</p> <pre><code>[ComImport, Guid("D032F796-167D-4B0D-851D-2AEEA226646A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMyDate { [MethodImplAttribute(MethodImplOptions.PreserveSig)] void Analyze_Date(ref int y, int m, int d); [MethodImplAttribute(MethodImplOptions.PreserveSig)] [return: MarshalAs(UnmanagedType.U1)] bool testing(); } </code></pre> <p>This interface matches up with a Delphi interface declared like this:</p> <pre><code>IMyDate = interface ['{D032F796-167D-4B0D-851D-2AEEA226646A}'] procedure Analyze_Date(var y: Integer; m, d: Integer); stdcall; function testing(): Boolean; stdcall; end; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload