Вызов C # dll из Delphi

#c# #.net #delphi #managed-code

#c# #.net #delphi #управляемый код

Вопрос:

Я создал .Net 3.5 dll с единственным методом, который должен вызываться Delphi .exe. К сожалению, это не работает.

Шаги: 1. Создайте C # 3.5 dll с кодом:

 public class MyDllClass
{
    public static int MyDllMethod(int i)
    {
        MessageBox.Show("The number is "   i.ToString());
    }
}
  
  1. Перейдите в свойства сборки —> Информация о сборке и проверил «Сделать сборку COM-видимой»
  2. Используется RegAsm.exe чтобы зарегистрировать мою dll

Это вызывает исключение Delphi, которое указывает, что не удается подключить dll. Какие шаги требуются, чтобы разрешить использование C # управляемой dll из неуправляемого кода.

Кто-нибудь знаком с хорошим примером по этому вопросу?

Спасибо

Комментарии:

1. Как именно вы пытаетесь подключить объект? Вы импортируете ее с помощью мастера (который генерирует для вас модуль-оболочку) или загружаете библиотеку напрямую?

2. Я нашел решение для этой проблемы — смотрите Ответ ниже

Ответ №1:

Возможно, вам повезет больше, если вы пропустите COM-часть, используя мой шаблон проекта для неуправляемого экспорта

 class MyDllClass
{
    [DllExport]
    static int MyDllMethod(int i)
    {
        MessageBox.Show("The number is "   i.ToString());
        return i   2;
    }
}
  

В Delphi вы бы импортировали его следующим образом:

 function MyDllMethod(i : Integer) : Integer; stdcall; extern 'YourAssembly.dll';
  

Однако мне пришлось отклонить ваш вопрос. За то, что даже не позаботился о том, чтобы предоставить код, который будет компилироваться. (ваш метод C # не возвращает значение, но он ожидает как int)

Комментарии:

1. Привет, Роберт, я не вижу шаблон после размещения zip-файла в нужном месте (Мои документы Visual Studio 20 ** Шаблоны ProjectTemplates). Я использую VS2010, вы знакомы с ним?

2. Вы загрузили UnmanagedExportLibrary.zip верно? Страница с примерами содержит ссылку на DllExport.zip , который является просто задачей сборки и некоторыми библиотеками, а не шаблоном. Если вы действительно использовали шаблон: Перейдите в Инструменты / Параметры / Проекты и решения. Там вы найдете свойство «Расположение шаблонов пользовательского проекта». Это папка, в которой VS будет искать шаблоны проекта.

3. Привет, Роберт. Я просто хочу спросить, есть ли у вас какие-либо идеи, почему я получаю нулевой адрес (без точки входа в dll), пытаясь использовать этот пример в Delphi?

4. @RobertGiesecke Как из C # /DLL вернуть строку в Delphi? Кроме того, регистрация параметра Delphi в C # / DLL допустима только в том случае, если возвращает функцию int.

5. @mih маршалинг по умолчанию эквивалентен PAnsiChar в Delphi. Если вы хотите использовать unicode, то вы можете пометить свою функцию в C # «[return: MarshalAs(UnmanagedType.BStr)]», а в Delphi это было бы PWideChar. но прошло много лет с тех пор, как я писал Delphi…

Ответ №2:

После масштабного исследования я нашел решение: все дело в параметрах регистрации. Флаг / кодовая база должны быть добавлены в команду regasm.

Во многих публикациях предлагается использовать Guid и другие COM-атрибуты для объекта, предоставляемого C # Com, мне удалось обеспечить функциональность COM с помощью атрибута ComVisible (true) и команды regasm / tlb / codebse.

Код:

 [Guid("7DEE7A79-C1C6-41E0-9989-582D97E0D9F2")]
[ComVisible(true)]
public class ServicesTester
{
    public ServicesTester()
    {
    }

    //[ComVisible(true)]
    public void TestMethod()
    {
        MessageBox.Show("You are in TestMEthod Function");
    }
}
  

и, как я уже упоминал, я использовал regasm.exe /tlb /codebase для ее регистрации

Комментарии:

1. Особая благодарность за то, что рассказали нам, что сработало!

Ответ №3:

Одна вещь, которая может быть проблемой, если вы создали свою сборку x64 или AnyCPU. Поскольку Delphi 32-разрядный (x86), вам нужно сделать вашу сборку x86 или убедиться, что regasm.exe регистрирует его также в 32-разрядном реестре. Вы делаете это, используя версию x86 для regasm.exe .