DllSurrogate не загружается из-за 0x8007065E «Данные этого типа не поддерживаются» - PullRequest
2 голосов
/ 08 июля 2019

Я пытаюсь сделать старую 32-битную DLL Delphi пригодной для использования из моих приложений на C #. Использование суррогата системной DLL по умолчанию (dllhost.exe) представляется наиболее удобным решением.

Чтобы доказать, что это будет работать, я создал минимальную 32-битную тестовую DLL с Delphi, которая просто реализует один интерфейс с одним методом

HRESULT Add(double a, double b, double* c);

В моей тестовой программе на C # я сначала использовал внутрипроцессную активацию, которая сработала. Но поскольку мы хотим преодолеть 32/64-битный барьер, мы должны использовать DLL Surrogate. Поэтому я добавил необходимые записи реестра (AppID и т. Д.), Чтобы сделать эту работу, но все еще держал оба модуля (тестовый проект DLL и C #) на данный момент 32-битными.

Чтобы убедиться, что DLL не загружена в процессе, я 'вызвал' CoCreateInstance и использовал его так:

var adapter = CoCreateInstance(
        new Guid("96810C5C-BA59-49D4-9732-EF902B8EFA72"),
        null,
        CLSCTX.CLSCTX_LOCAL_SERVER,
        new Guid("00000000-0000-0000-C000-000000000046"));

Последний GUID - IUnknown, поэтому я даже не использую свой пользовательский интерфейс для этого теста (конечно, я начал с моего пользовательского интерфейса).

Проблема в том, что этот код уже не работает с:

0x8007065E "Data of this type not supported"

и я понятия не имею, о каких данных идет речь. Я подумал, что, возможно, будут поддерживаться только типы VARIANT, поэтому я изменил свою подпись на следующую и для теста даже пропустил параметр 'out':

HRESULT Add(VARIANT a, VARIANT b);

Все та же ошибка!

Есть идеи, что здесь не так?

Обновление 1

Объявление CoCreateInstance это

[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);

Обновление 2

Для полноты следует отметить, что в Delphi интерфейс разработан с помощью редактора библиотеки типов Delphi. Затем в C # я импортирую COM-объект как ссылку, которая, afaik, создает оболочку из библиотеки типов.

Обновление 3

Я только что реализовал тот же тестовый объект COM с C # и сделал его видимым для COM. Я даже не импортировал библиотеку типов для создания оболочки-оболочки, которую можно вызвать во время выполнения, а только пытался получить IUnknown с CoCreateInstance. То же сообщение об ошибке! (Кстати, мой тестовый компьютер работает под управлением Windows 10)

Обновление 4

Я переписал клиента в Delphi и создал экземпляры обеих реализаций COM-объектов (Delphi и C #) с помощью суррогата DLL. То же сообщение об ошибке от CoCreateInstance!

1 Ответ

0 голосов
/ 08 июля 2019

Как оказалось, все это большое заблуждение было вызвано неправильной настройкой реестра. Значение DllSurrogate, которое необходимо добавить в запись AppID для моего COM-объекта, должно быть пустым, чтобы использовать системный файл по умолчанию dllhost.exe. Однако он все еще должен иметь тип REG_SZ, и мой случайно был создан как REG_BINARY.

...