Есть несколько способов сделать это, и традиционный COM / Interop - только один способ сделать это.
Другим способом является использование уже существующей инфраструктуры, встроенной в CLR, для поддержки COM / Interop и смешанного режима C ++ / CLI.
- CLR отлично поддерживает маршалинг ссылок на интерфейсы и из IUnknown (и каждый интерфейс Delphi удовлетворяет этому требованию)
- Вы можете превратить сборки .Net в реальные библиотеки DLL и экспортировать функции на любом языке
- Я написал задачу MSBuild, которая делает это полностью прозрачным: http://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
- Объедините эти две вещи, и вы получите компонент .Net в качестве ссылки на интерфейс без необходимости бороться с COM и clsids / progids
К счастью для вас, я уже ответил на очень похожий вопрос на другом форуме. Поэтому у меня уже был пример кода для начала. ; -)
То, что я показываю здесь, может не быть вашей чашкой чая.
- Требуются, по крайней мере, некоторые знания .Net, которые вы, возможно, не хотите связывать слишком много.
- Требуются ручные действия с обеих сторон, и хотя гибкость, которую вы приобретаете, может легко сделать ее более чем достойной, гибкость может просто не требоваться. Таким образом, классический COM может быть вариантом.
В конце концов, я бы сам не использовал классический COM. Если это действительно имеет смысл. (Например, написание COM-надстроек для Office)
В VisualStudio вы можете использовать мастер интерфейса рефакторинга / извлечения для получения интерфейса от вашего компонента, который имеет необходимые вам методы.
Вы должны предоставить эти 3 атрибута
[ComVisible(true)]
[Guid("Create a GUID yourself"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IYourInterface
- Требуется «ComVisible», иначе CLR не создаст требуемую оболочку, вызываемую во время выполнения (RCW) (то, что будет видно из Delphi)
- GUID требуется для идентификации интерфейсов, GUID должен быть одинаковым в Delphi и .Net версии вашего интерфейса
- «ComInterfaceType.InterfaceIsIUnknown» сообщает CLR, что RCW должен реализовать IUnknown.
Без этого вы не сможете использовать его в Delphi. Потому что в Delphi каждый интерфейс IUnknown.
Ради простоты я предполагаю, что у вашего компонента есть только один простой метод.
Создайте библиотеку классов в VisualStudio и следуйте инструкциям на другой странице. (Чтобы можно было экспортировать функции)
[ComVisible(true)]
[Guid("Create a GUID yourself"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IYourInterface
{
void DoSomething(int value);
}
public class YourComponent : IYourInterface
{
public void DoSomething(int value)
{
return value + 1;
}
}
static class Exports
{
[DllExport("createyourcomponent")]
public static void CreateInstance([MarshalAs(UnmanagedType.Interface)]out IYourInterface instance)
{
instance = new YourComponent();
}
}
В Delphi вы можете обернуть этот интерфейс в компонент, если хотите.
Что бы скрыть тот факт, что .Net участвует:
type
IYourInterface = interface
['{Create a GUID yourself}']//Control+Shift+G in Delphi
// important, safecall is used by COM/Interop
procedure DoSomething(aValue : Integer); safecall;
end;
TYourComponent = class(TComponent)
private
fInnerInstance : IYourInterface;
public
procedure DoSomething(aValue : Integer);
constructor Create(aOwner : TComponent);
end;
implementation
procedure CreateManagedInstance(out aInstance : IYourInterface);
stdcall; external 'YourDotNetLibraryName'
name 'createyourcomponent';
constructor TYourComponent.Create(aOwner : TComponent);
begin
inherited Create(aOwner);
CreateManagedInstance(fInnerInstance);
end;
procedure TYourComponent.DoSomething(aValue : Integer);
begin
fInnerInstance.DoSomething(aValue);
end;
Отказ от ответственности: у меня не было удобной IDE, поэтому в примере кода могут быть опечатки или другие ошибки ...