7

We are on the verge of writing a C# web service that will expose functionality contained in a native Delphi GUI app. Why would I choose to wrap the Delphi code in a native dll and why would I want to wrap it in a COM server? In other words: what factors do I need to consider when choosing one over the other? I am interested in factors with regard to coding, debugging, (automated) testing, deployment (installation at customers) and performance (overhead?).

Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
  • 1
    Can you not just re-write the functionality in C#? Sounds like a maintenance nightmare! – Belogix Aug 21 '13 at 09:05
  • It does sound like a nightmare project, is the delphi code all in an exe or split into libraries? Anyway COM servers would require an installation on the client, where a C library would just need to be bundled with the rest of the files – CurlyPaul Aug 21 '13 at 09:08
  • @Belogix: That may/is be the end-goal, but is not an option at the moment given the time constraints we are under. The alternative would be to create a Delphi web service, but developer availability says we need to move towards C#. – Marjan Venema Aug 21 '13 at 09:13
  • Because and whatever you can, most likely. This Q makes no sense for me besides invitation to long lasting and pointless argument. – OnTheFly Aug 21 '13 at 09:31
  • 5
    @OnTheFly: Don't see it that way. It think it should be possible to answer with objective advantages and disadvantages of using one versus the other. – Marjan Venema Aug 21 '13 at 09:36
  • Then you should state **specific** objective factors instead of just being broadly *"interested in"*. What specifically makes you lean toward solution X and what toward Y? – OnTheFly Aug 21 '13 at 09:44
  • @OnTheFly: if you can give more specific factors than the aspects I already mentioned, I am all ears... – Marjan Venema Aug 21 '13 at 09:49
  • Otherwise you're all tongue :-) As I said - pointless. Throw a dice. – OnTheFly Aug 21 '13 at 10:00
  • @OnTheFly: Ah, you have been looking me up have you? Well, I guess the point is that I am trying to discover what should make me lean towards X or Y. Have done close to zero work in interop and have no idea where to begin making a decision, when I do know that a decision for either will have consequences that may bite us in the behind when we are further along and less willing to change tack. – Marjan Venema Aug 21 '13 at 10:02
  • In my view the decision comes down to surface area of interop interface. Small interface -> p/invoke. Large interface -> COM. Also personal experience. If you know COM well, it's a sound choice. If you are familiar with interop to C style DLLs, p/invoke. – David Heffernan Aug 21 '13 at 12:36
  • Thanks @David. Personally have more experience with COM, at least one team member has experience with C style DLLs... Don't know (yet) about the others. Will certainly throw this in during our discussions. – Marjan Venema Aug 21 '13 at 13:33
  • 1
    Do you plan to use DCOM at all? It's DCOM and DCOMCNFG.exe I hate. COM (in process) is actually staggeringly easy, and reliable. COM was invented to safe you from all the hard work and shooting-in-foot that raw DLL implementations bring with them. I would be very wary of anybody who wants to do it all raw and low level. – Warren P Aug 21 '13 at 19:31
  • @WarrenP: Nope, no DCOM. Delphi code wrapped in native or com dll will always be on the same machine as the C# web service using it. I am leaning towards COM as well. Getting push back on (supposed) overhead and registration issues. – Marjan Venema Aug 21 '13 at 19:36
  • I suppose then, COM is certainly the best option. I would argue for it on the basis of it being an ABI with Guaranteed Binary Stability, Interfaces, and Memory Safety, and having been invented expressly because native C-style DLL APIs are so difficult to do safely, properly, and in a way that correctly handles interoperability, discoverability, and ABI versioning. – Warren P Aug 21 '13 at 19:49
  • I'm with @WarrenP. COM is the correct (or even the standard) way to go IMHO. using a native DLL with a C# web service is a twisted concept to begin with. once you create the COM object in your C# code, all methods are clearly exposed, COM variables and types are compatible, you don't need to play with pointers or worry about memory management and thread safety. I often quickly debug/test my COM server locally with VBS or JS. the only better way, is to rewrite Delphi code to C# (which is exactly what we are doing now after 10 years of using a COM server with ASP - after we moved to .NET and C#) – kobik Aug 22 '13 at 08:29
  • @WarrenP: Thanks for your comment. The Guaranteed Binary Stability is especially convincing. – Marjan Venema Aug 22 '13 at 08:39
  • @kobik: yes, the rewrite is on the cars, we are only looking at interop as a way to expose the functionality through the web service without having to wait for a full rewrite to be finished. Ease of use and safety of the temporary solution are indeed important factors to consider. Thanks. – Marjan Venema Aug 22 '13 at 08:43
  • There's no guaranteed binary stability? What on earth does that even mean? No advantages in terms of versioning. P/invoking to C style functions is actually very easy if you know how. – David Heffernan Aug 22 '13 at 10:51
  • @DavidHeffernan: I don't know, WarrenP was talking about that? – Marjan Venema Aug 22 '13 at 12:02
  • By binary stability, I am referring to some slightly more complex scenarios than a `void foo(int,int,int)`. As you well know, COM allows interfaced types in the parameter lists, and these interfaced complex types allow us to communicate our complex types via passing in interfaces. This is the area where binary stability comes in. Imagine you have `struct` types and a `struct *` in a raw-C-style-DLL. Now think about stability over time. – Warren P Aug 22 '13 at 12:55

1 Answers1

3

COM adds some significant advantages over a plain DLL:

  • Support for OOP (classes, interfaces)
  • Automatic memory management for strings (BSTR), arrays and objects (via interfaces)
  • No need to use platform invoke on the .NET side

So I would go for COM.

To use a Delphi class in .NET using a DLL you have to flatten the class on the Delphi side and rewrap it on the .NET side, which is kind of ugly.

A lot of Rudy's article on Delphi and C++ code applies to C# as well:

http://rvelthuis.de/articles/articles-cppobjs.html

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • Good points, thanks. Do you see any drawbacks to using COM (apart from having to register a COM server during install)? – Marjan Venema Aug 21 '13 at 10:03
  • 2
    Plain DLL can expose interface pointer to the client just the same way as COM server do. – OnTheFly Aug 21 '13 at 10:05
  • 1
    In newer Windows versions there is also Registration-Free COM. – Jens Mühlenhoff Aug 21 '13 at 10:05
  • Thanks, didn't know that, will be looking up registration-free COM asap. – Marjan Venema Aug 21 '13 at 10:07
  • 1
    There are some excellent explainations on registration free COM on SO: http://stackoverflow.com/questions/5074563/registration-free-com-dll – Jens Mühlenhoff Aug 21 '13 at 10:11
  • 1
    You don't need reg free COM. You just need a few p/invoked functions that return COM compatible interfaces. Well, they should be passed as var params because Delphi's return value ABI is bogus and non-standard. – David Heffernan Aug 21 '13 at 12:28
  • Sure, you can use COM without an actual COM server like OnTheFly suggested. That would be a good approach if your DLL is not intended for use outside of your application. – Jens Mühlenhoff Aug 21 '13 at 14:56
  • Dll is not intended for use outside of my application. Have a hard time though seeing the advantage in "COM without an actual COM server"? Wouldn't that mean that we'd have to do everything a COM server does in our own code? Note: I have plenty of experience using COM and writing COM servers, but using vcl provided stuff and have never delved into COM spec/working innards. – Marjan Venema Aug 21 '13 at 19:40
  • You don't have to register the DLL or set up reg-free COM, you can just write a simple function that returns a COM interface using a var param that you P/Invoke. Of course with a COM server you don't have to P/Invoke anything, so YMMV. – Jens Mühlenhoff Aug 22 '13 at 09:26