Вопрос

У меня есть DLL Delphi с функцией, определенной как:

функция SubmitJobStringList(список заданий:тСтроковый список;вар задание нет:Целое число):Целое число;

Я вызываю это из С#.Как объявить первый параметр, поскольку tStringList не существует в C#.В настоящее время у меня есть декларация как:

[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);

Но когда я вызываю его, я получаю исключение нарушения доступа к памяти.

Кто-нибудь знает, как правильно перейти к tStringList из С#?

Это было полезно?

Решение

С этим вам, скорее всего, не повезет.TStringList — это больше, чем просто массив, это полноценный класс, и точные детали реализации могут отличаться от того, что возможно в .NET.Взгляните на исходный код Delphi VCL (то есть, если он у вас есть) и попытайтесь выяснить, можете ли вы пересобрать класс на C# и передать его с помощью вашего лучшего друга, Interop Marshaller.Обратите внимание, что даже строковый тип Delphi отличается от строкового типа .NET, и, передавая его, не сообщая маршаллеру, что ему следует делать, он, скорее всего, передаст его как массив символов.

Помимо этого, я бы предложил изменить DLL Delphi.Никогда не стоит раскрывать что-либо, специфичное для Delphi, в DLL, которая будет использоваться клиентами, не являющимися Delphi.Сделайте параметр массивом PChar, и все будет в порядке.

Другие советы

Если это ваша DLL, я бы переписал функцию, чтобы она принимала массив строк.Избегайте передачи классов в качестве параметров DLL.

Или, если вы Действительно по какой-то причине вы хотите использовать TStringList, Delphi VCL.Net можно использовать с любого языка .Net.

Старый пример использования TIniFile: http://cc.codegear.com/Item/22691

В примере используется .Net 1.1 в Delphi 2005.Delphi 2006 и 2007 поддерживают .Net 2.0.

Если вы не контролируете DLL, и они не могут или не хотят ее изменить, вы всегда можете написать свою собственную оболочку Delphi в отдельной DLL с параметрами, которые более удобны для разных языков.

Иметь класс в качестве параметра функции DLL — это действительно плохой тон.

Мне не совсем понятен ваш способ использования Delphi и C#.Кажется, вы создали DLL Win32, которую хотите вызвать из C#.Конечно, для этого вы должны использовать PInvoke.

Я бы посоветовал вам создать .NET DLL, используя ваш исходный код, поскольку доступен полный перенос VCL.Если хотите, могу подробнее....

Теоретически, вы мог сделайте что-то подобное, используя указатели (приведя их к типу C# IntPtr) вместо строго типизированных ссылок на объекты (или, возможно, обернув их в какой-то другой тип, чтобы избежать необходимости объявлять небезопасные блоки), но основная загвоздка заключается в следующем:Среда выполнения Delphi должна быть механизмом выделения и освобождения памяти для объектов.С этой целью вы должны объявить функции в вашей скомпилированной Delphi DLL, которые вызывают конструкторы и деструкторы для класса TStringList, вы должны убедиться, что ваша Delphi DLL использует модуль ShareMem, и вы должны взять на себя ответственность за увеличение и уменьшение счетчика ссылок. для ваших AnsiStrings Delphi до того, как они покинут DLL и после того, как войдут в нее, желательно также как функции, экспортированные из вашей DLL Delphi.

Короче говоря, это много работы, поскольку вам нужно совмещать два менеджера памяти в одном процессе (.NET CLR и распределители Delphi), и вы оба должны управлять памятью вручную. и «обмануть» менеджер памяти Delphi и среду выполнения.Есть ли какая-то особая причина, по которой вы привязаны к этой установке?Не могли бы вы описать проблему, которую вы пытаетесь решить на более высоком уровне?

Как сказал Хемант Джангид, вы легко сможете сделать это, скомпилировав свой код как dll .NET, а затем обратившись к этой сборке в своем проекте C#.

Конечно, вы сможете это сделать только в том случае, если ваша версия Delphi поддерживает Delphi.NET.

Я мало что знаю о C#, но метод, который я использую для транспортировки списков строк между контекстами, заключается в использовании свойства .text для получения строки, представляющей список, а затем присвоения этого свойства «другой стороне».

Обычно легче перекинуть веревку через стену, поскольку это полноценный объект.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top