4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
||||||||||||||||
1 | ||||||||||||||||
Неуправляемая dll (delphi) не может менять свои данные24.10.2013, 12:29. Показов 1281. Ответов 15
Метки нет (Все метки)
Начну с вопроса: если неуправляемый код сам выделяет память и создает объект, доступен ли он при следующих вызовах неуправляемого кода?
Есть некая dll, от которой известно описание объектов и заголовков функций. При помощи вызова одной из функций dll сама создаёт в памяти некую сложную структуру, и вызовами других функций вносит изменения в поля структуры. Первый вызов с созданием структуры (и её начальным наполнением) удалось наладить, возвращается указатель на красивую структуру. Но дальше проблемы - при вызове последующих функций dll ругается на неопределенные ошибки (видимо Exception), и данные в структуре не меняет. Цитаты из кода:
А res2 = -1 (общая ошибка, как по описанию dll). Дело вряд ли в самой функции FillCharges, вместо неё испробовано ещё с десяток предлагаемых в dll функций, с разными входными параметрами и проч. У кого есть опыт работы с неуправляемым кодом, прошу поделиться соображениями.
0
|
24.10.2013, 12:29 | |
Ответы с готовыми решениями:
15
C# и неуправляемая Dll Borland C++ Builder 6.0 не может найти свои же dll файлы Неуправляемая DLL библиотека. Импорт, создание класса библиотеки Функция может менять глобальные данные и сохраняются ли эти изменения |
24.10.2013, 12:59 | 2 |
В общем сказать нельзя. Но если этот объект не замочили, между первым и вторым вызовом, то должен быть доступен.
Добавлено через 2 минуты Да, вопрос - там у вас точно объект? Если вы без COM-интерфейсов и т.п. читаете в C# дельфийскую структуру, может, там record? А record-ы дельфи мочит, при уходе из области видимости.
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
|
24.10.2013, 13:05 [ТС] | 3 |
А кто мочит объекты в неуправляемой памяти? GC ведь туда не лезет, как я понимаю.
При отладке, по указателю все данные видны. Может маршалинг после преобразования ответа и ref параметров блокирует все результаты деятельности неуправляемого метода? И кто подскажет, может какие дебарегы дополнительные есть, чтобы понять проблему... У кого был подобный опыт многократных вызовов неуправляемого кода? Там record, dll его создаёт и возвращает указатель. Для освобождения памяти предусмотрена отдельная процедура.
0
|
24.10.2013, 13:14 | 4 |
Ну мало ли. Например, интерфейсные объекты удаляются при обнулении ссылок, тоже своеобразная сборка мусора. Дотнетовский GC, конечно, не залезает.
Ну, тут только дельфийским дебаггером эту dll отлаживать. Тогда вполне возможно, что этот рекорд удаляется при выходе из процедуры, где создаётся. Позаботьтесь, чтобы не удалялся. Например, перенесите в более высокую область видимости. Или выделите для него память вручную, чтобы самому контролировать удаление (оператор new). Добавлено через 2 минуты Да, кстати, почему тут класс, если из dephi приходит record? Это ведь оно, я так понимаю?
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
|||||||||||
24.10.2013, 14:44 [ТС] | 5 | ||||||||||
Да, это оно. Был там и struct, эффект тот же. Это я пытался пробовать варианты возврата указателя на структуру. Это ОНО вообще достойно отдельной темы. Две недели добивался как правильно сделать маршалинг. В этом record'е сплошные указатели на массивы, причем иногда указатели на массивы других record'ов.
Как я писал выше, стартовый метод dll возвращает указатель на созданную структуру, и есть финальный метод, для освобождения этой структуры. Из этого я делаю вывод, что dll сама выделяет память под структуру, и освобождает только при вызове финального метода. Сама dll предусматривает работу с ней внешней системы в виде вызова многих отдельных методов, которые работают со структурой.
0
|
Почетный модератор
|
|
24.10.2013, 14:54 | 6 |
Slyfish, приведите определения функций и структур на Delphi, обычно такое поведение из-за некорректного объявления. Также было бы хорошо увидеть саму DLL.
Отлаживать можно через Windbg + SOS(EX) для работы с .NET'ом.
0
|
24.10.2013, 14:57 | 7 | ||||||||||
Увы, это не ответ на вопрос - а не убивается ли ваша структура раньше времени.
Ну это ведь только так предполагается, верно? Напишите, как вы создаёте вашу структуру. Не описание типа, а само создание, внутри GetAccount, как именно вы выделяете под неё память. Если как-то так:
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
|||||||||||
24.10.2013, 15:28 [ТС] | 8 | ||||||||||
Привожу выдержки из описания dll
Добавлено через 1 минуту Увы, dll предоставлена в виде черного ящика, исходного кода нет.
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
|
24.10.2013, 15:37 [ТС] | 10 |
Не только другие не жаловались, мы сами на Delphi 7 писали работу с этой dll. И всё прекрасно. Теперь вот встала необходимость сделать сетевую версию, и решили уходить от древностей. Тем более что на Delphi 7 с сетью тоже какие-то заморочки нам насыпались.
0
|
Почетный модератор
|
|
24.10.2013, 15:48 | 11 |
Смущает вот этот момент
Откуда взялись public int CntDataXLen ? Если Вы к этим данным не обращаетесь, то по идее ничего страшно произойти не должно, т.к. структура получается больше по размеру, плохо было бы если б меньше. И да, uInfo должен быть классом (как Вы определили в самом начале), т.к. var в Delphi говорит что передаваемое значение может быть изменено, если использовать структуры тогда в методе GetAccount нужно использовать IntPtr, но это так не заметку...
1
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
||||||
24.10.2013, 16:01 [ТС] | 12 | |||||
Я, видимо, так и не смог правильно описать подходящую структуру в управляемом коде. Здесь надо использовать SizeConst=2, или подобное? Как я уже писал, маршалинг этой структуры достоин отдельной темы.
Но пока до этой структуры дело не доходит, разве не так? С целью проверить, что происходит, я пока достаю остальные данные из созданной структуры, игнорируя этот кусок. Да и при отладке уже видно, что данные не меняются. Добавлено через 3 минуты
0
|
Почетный модератор
|
||||||
24.10.2013, 16:07 | 13 | |||||
Судя по структуре всё правильно, за исключением CntDataX. В Delphi если не ошибаюсь это array [0..1] массив из 2х элементов, в C# это можно заменить двумя IntPtr:
Без отладки довольно трудно сказать в чем дело, была бы DLL тогда можно было бы попробовать посмотреть где именно происходит ошибка выполнения и почему. Что еще можно попробовать - сравнить размеры структур и смещения полей в Delphi (работая в самой среде) и в C# (с помощью Marshal.SizeOf и Marshal.OffsetOf)
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
||||||
24.10.2013, 16:18 [ТС] | 14 | |||||
NickoTin, Вы полагаете, несовпадение полей или размеров всей структуры в управляемом коде всё же может влиять на работу dll со своими "родными" данными, которые она только что создала сама?
Провел эксперимент. Выключим маршалинг совсем:
0
|
4 / 0 / 0
Регистрация: 24.10.2013
Сообщений: 8
|
|
25.10.2013, 12:57 [ТС] | 16 |
Решение найдено. Увы, банальная невнимательность. Кто читал тему, тоже не прошел этот тест
Delphi: function GetAccount(Adr1, Adr2: Integer; var Info: PInfo): Integer; stdcall; function FillCharges(Info: PInfo; Mode: Integer): Integer; stdcall; C#: uInfo inf = null; int res = GetAccount(Adr1, Adr2, ref inf); int res2 = FillCharges(ref inf, 1); При вызове FillCharges получился указатель на указатель, хотя требуется просто сам указатель.
0
|
25.10.2013, 12:57 | |
25.10.2013, 12:57 | |
Помогаю со студенческими работами здесь
16
Получить данные через указатель из dll на delphi Кто может поделиться файлами ogg.dll, vorbis.dll и vorbisfile.dll - 32-х и 64-битными версиями? После загрузки приложения картинки должны менять свои координаты случайным образом Как сделать, чтобы пользователи могли вводить или менять свои пароли в окне приветствия удаленного компьютера? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |