4

I have this situation where I need to create an unmanaged DLL in .Net that can be invoked from a delphi program. I've been doing some research and I found Robert Giesecke's library (RGiesecke.DllExport). I started with a pretty simple DLL that displays a windows form with a textbox, something like this:

[ComVisible(true)]
[DllExport("PlaceOrder", CallingConvention = CallingConvention.StdCall)]
public static IntPtr PlaceOrder(IntPtr lnpInXml)
{
    string inputXml = Marshal.PtrToStringAnsi(lnpInXml);
    StringBuilder sbOutputXml = new StringBuilder();

    Form1 pti = new Form1(inputXml, sbOutputXml);
    pti.ShowDialog();

    return Marshal.StringToHGlobalAnsi(sbOutputXml.ToString());
}

This works fine, I setup the delphi program to invoke my dll and it works just fine. The problem comes when I add a reference to another project in my solution and create an instance of an object inside that project. At that point, the delphi program stops displaying the form like it couldn't find the exported function but it doesn't throw any errors either:

using MyCommonCode;

namespace UnmanagedDLLTest
{
    [ComVisible(true)]
    public static class UnmanagedDLL
    {
        [ComVisible(true)]
        [DllExport("PlaceOrder", CallingConvention = CallingConvention.StdCall)]
        public static IntPtr PlaceOrder(IntPtr lnpInXml)
        {
            string inputXml = Marshal.PtrToStringAnsi(lnpInXml);
            StringBuilder sbOutputXml = new StringBuilder();

            Form1 pti = new Form1(inputXml, sbOutputXml);
            pti.ShowDialog();

            MyCommonCode.MyClass mc = new MyCommonCode.MyClass();

            return Marshal.StringToHGlobalAnsi(sbOutputXml.ToString());
        }
    }
}

This line:

MyCommonCode.MyClass mc = new MyCommonCode.MyClass();

is the source of my problem, as soon as I comment it everything works again. I've been looking for examples like this on google for a while, but everything I find is similar to my first piece of code. Any ideas would be really appreciated at this point, I'm starting to think it isn't possible :(.

Regards.

camendez
  • 43
  • 3
  • [ComVisible(true)] is not needed. Are you sure this another .dll is copied to the same folder where delphi program is trying to load your assembly? – Konstantin Tarkus Jan 27 '14 at 05:57
  • You cannot ignore exceptions in this scenario, Delphi code doesn't stand a chance to tell you why the C# code crashed. Surely the underlying problem is that it cannot find the DLL that contains MyClass. But that's just a guess, focus on better error handling inside the C# code itself. Use try/catch and some way to display or log an exception. You'd be well ahead by *really* using the [ComVisible] attribute btw, Delphi support COM well and you'll have a way to diagnose and report errors. – Hans Passant Jan 27 '14 at 10:39
  • Thanks for your ideas guys. That was my first thought when it stopped working, so I moved all my dll's to the same folder where the delphi program is looking for the initial dll (it still didn't work). I'll try adding Nlog to that method to store any exceptions on a file. If that doesn't work I'll try COM. – camendez Jan 27 '14 at 14:08
  • COM cannot help. You are bound by the interface of the host app. UnmanagedExports is a fine solution. I'd actually try with a different host that you write from scratch in say C++ or Python. Prove that the Delphi app is working as you believe. Also try debugging the managed app. Step through and see if there are exceptions raised. – David Heffernan Jan 28 '14 at 23:03

1 Answers1

1

I have that same problem. In my case, I trying to call a C# DLL from a Visual FoxPro application. As long as a method makes a call to an external DLL, the FoxPro application returns an error/exception.

I recommend that you follow this guide from another StackOverflow question. Basically:

  1. Create the a COM visible C# dll
  2. Register the DLL on the deploy machine using regasm
Community
  • 1
  • 1
dialex
  • 2,706
  • 8
  • 44
  • 74