2

I have a COM class created in VB.NET. I am trying to use it in Delphi 5.0.

I have seen some examples/questions on the topic, namely:

Call C# dll from Delphi

http://www.drbob42.com/delphi/headconv.htm

http://edn.embarcadero.com/article/32754

and others, but these all deal with basic functions and not custom objects.

Firstly, I have registered my VB.NET COM DLL using regasm.

My VB.NET COM object is defined as follows:

<ComClass(Bridge.ClassId, Bridge.InterfaceId, Bridge.EventsId)> _
Public Class Bridge

  ' A creatable COM class must have a Public Sub New() 
  ' with no parameters, otherwise, the class will not be 
  ' registered in the COM registry and cannot be created 
  ' via CreateObject.
  Public Sub New()
    MyBase.New()
  End Sub

  Public Function Quote(ByRef input As InObject) As ReturnObject
    BLABLA
  End Function

End Class

With an Input class:

<ComClass(InObject.ClassId, InObject.InterfaceId, InObject.EventsId)> _
Public Class InObject

End Class

And a Result class:

<ComClass(ReturnObject.ClassId, ReturnObject.InterfaceId, ReturnObject.EventsId)> _
Public Class ReturnObject

End Class

Please pay no attention to the class names and lack of code in them. I just want to highlight how I am defining them as COM classes.

I can't find any examples of Delphi code calling a method in a COM class, or one that uses custom objects as inputs and returns. But, from the examples I showed above, I thought the line in Delphi to declare the function for use would be like this:

function Bridge.Quote(i: InObject): ReturnObject; external 'Bridge.dll';

This fails to compile. I get an error:

function needs result type

Is there anything obvious that I am doing wrong?

Community
  • 1
  • 1
user260495
  • 117
  • 2
  • 13
  • I said in the middle of my post that I altered the names to simplify things, all I wanted to show with the .NET code is how the COM classes are registered so names can be ignored. Thanks. – user260495 Sep 09 '16 at 10:09
  • I can't put the _actual_ code here. Updated class names in case people miss my comment about them – user260495 Sep 09 '16 at 11:31
  • Try `Variant` instead of `ReturnObject` in your Delphi function declaration. – 500 - Internal Server Error Sep 09 '16 at 23:04
  • That didn't work either, same error message. – user260495 Sep 12 '16 at 12:57
  • 2
    You can't use an `external` statement to import a COM object. You need to define the object's COM interfaces in Pascal code and then use `CoCreateInstance()` or equivalent function to instantiate the COM object at runtime, and then use the interfaces to access it. You can have the Delphi IDE import the .NET assembly so it can extract the relevant COM declarations and generate suitable Pascal code for you. – Remy Lebeau Sep 12 '16 at 23:15

2 Answers2

2

To create the ComObject you have 2 options:

  • CoCreateInstance
    https://msdn.microsoft.com/de-de/library/windows/desktop/ms686615(v=vs.85).aspx
    This requires the ComObject to be registered as you described before. You can call it like:

    CoCreateInstance(YourClassID, nil, CLSCTX_INPROC_SERVER, YourInterfaceID, Result)

  • Your DLL Exports a function which creates the requested Instance. You can then import this function when loading the DLL. No registration required.

    function MyFunc: IMyInterface; external 'MyDll.dll';

Do not forget to use a suitable callingconvention which both languages support(like stdcall or cdecl)

Alexander B.
  • 120
  • 1
  • 9
  • Thanks for your reply. I went down the road of importing the tlb file in the delphi IDE then using Co Create, so I have something like `bridge := CoBridge.Create; input := CoInObject.Create; bridge.Quote(input);` – user260495 Sep 13 '16 at 08:46
  • Sorry forgot to add the end of the line and can't edit the comment. With this though I get a generic error in my log file saying 'The system cannot find the file specified' I am think this is about not finding the dll. I registered the dll using regasm but am unsure if I have missed something here. Do you think I should ditch this approach and follow what you have outlined? – user260495 Sep 13 '16 at 08:55
  • Is the Com-DLL the same platform as your executable? I'd asume you can not mix WIn32/Win64 – Alexander B. Sep 13 '16 at 09:49
  • The com DLL is build using VB and it is compiled on windows 7 but compiled to 32bit (x86). The delphi code is running on XP. – user260495 Sep 13 '16 at 10:10
  • are all dependencies availaible on the XP-Machine? Please try to get it work on the W7 machine first. – Alexander B. Sep 13 '16 at 10:28
  • The delphi code etc will only work on the xp machine - don't really want to think about porting that to windows 7. I wrote a vb.net applicaiton to call the dll and this works on both windows 7 and xp. Therefore the dependencies must be satisfied on both. So I am guessing my delphi application can't see the vb.net dll, would you agree? – user260495 Sep 13 '16 at 14:36
  • mhh somehow yes. But i think it might be registered wrong all along, maybe? Is it required that you wrote it in VB.Net? I am sure there is some functionality which was just easier to solve there? – Alexander B. Sep 13 '16 at 15:01
  • The delphi code and vb.net dll I am stuck with. The vb.net test harness that I just wrote I can write in anything if it helps diagnose? – user260495 Sep 13 '16 at 15:12
1

Thanks to Alexander B for sending me down the right direction - there were a few more details I have to add otherwise I would select his input as the correct answer.

So, as I stated in my comments, I imported the tld file in the delphi GUI and used the CoClassName.Create to get access to the objects. Though this gave me errors at run time as the application couldn't find the VB.NET dll, I got the error message 'The system cannot find the file specified' even though I had imported the dll using regasm. I then found the following post

Call C# dll from Delphi

Which states that the flag /codebase must be added to the regasm command. Once I imported the dll using regasm with this flag everything worked perfectly. Hope this helps someone else.

Community
  • 1
  • 1
user260495
  • 117
  • 2
  • 13