I am trying to make an old Delphi 32-bit DLL usable from my C# applications. Using the default system DLL surrogate (dllhost.exe) seems to be the most comfortable solution.
To prove this would work I created a minimal 32-bit test DLL with Delphi that just implements one interface with one method
HRESULT Add(double a, double b, double* c);
In my C# test program I first used in-process activation which worked. But because be want to break through the 32/64-bit barrier we have to use the DLL Surrogate. So I added the necessary registry entries (AppID etc.) to make this work but still kept both modules (DLL and C# test project) in 32-bit for the moment.
To make sure that the DLL is not loaded in-process I 'pinvoked' CoCreateInstance and used it like this:
var adapter = CoCreateInstance(
new Guid("96810C5C-BA59-49D4-9732-EF902B8EFA72"),
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
new Guid("00000000-0000-0000-C000-000000000046"));
The latter GUID is IUnknown, so I am not even using my custom interface for this test (of course I started with my custom interface).
The problem is that this code already fails with:
0x8007065E "Data of this type not supported"
and I have no idea what data it is talking about. I thought that maybe only VARIANT types would be supported so I changed my signature to the following and, for a test, even left out the 'out' parameter:
HRESULT Add(VARIANT a, VARIANT b);
Still the same error!
Any idea what is wrong here?
Update 1
The declaration of CoCreateInstance is this
[Flags]
enum CLSCTX : uint
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_INPROC_SERVER16 = 0x8,
CLSCTX_REMOTE_SERVER = 0x10
}
[DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
Update 2
For completeness I should mention that in Delphi the interface is designed via the Delphi type library editor. In C# I then import the COM object as a reference which, afaik, creates a wrapper from the type library.
Update 3
I just implemented the same COM test object with C# and made it COM-visible. I did not even import the type library to create a runtime-callable-wrapper but only tried to get an IUnknown with CoCreateInstance. Same error message! (BTW my test machine runs Windows 10)
Update 4
I rewrote the client in Delphi and instantiated both COM object implementations (Delphi and C#) via DLL surrogate. Same error message from CoCreateInstance!
As it turned out all this great confusion was caused by an incorrect registry setting. The DllSurrogate value that is to be added to the AppID entry for my COM object must be left empty to use the system default dllhost.exe. However it still must be of type REG_SZ and mine was accidentally created as REG_BINARY.
User contributions licensed under CC BY-SA 3.0