Утечка памяти при работе с С++ dll
От: kerimovmv  
Дата: 13.01.06 15:45
Оценка:
Привет,

У меня следующая проблема. Есть dll написаная на VC++ 6.0. которая экспортируют функцию:

extern "C" _declspec(dllexport) TestSt* Test(char* Language, char* Question, bool IsDefault, int CustomCount)

где,

typedef struct stRecordData_tag
{
int DocWeight; // Document weight
char* Title; // Document title
char* DocKey; // Document key
char* BestSentences; // Document summary
}RecordData;

typedef struct stTestSt
{
RecordData* RD[1000];
int MaximumCount;
int ReturnCount;
char * Error;
}
TestSt;

Я вызываю эту библиотеку из C# следующим образом:

//.........сама библиотека
[DllImport("ViaFactsQuery.dll")]
public static extern IntPtr Test(string Language, string Question, bool IsDefault, int CustomCount);

//.................... использованные классы
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public class CRecordData
{
public int DocWeight; // Document weight
public string Title; // Document title
public string DocKey; // Document key
public string BestSentences; // Document summary
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct CTestSt
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst=1000 )]
public IntPtr[] RD;
public int MaximumCount;
public int ReturnCount;
public string Error;
}
//......непосредственный вызов
IntPtr pts=Test(lang.ToUpper(),
Query,
IsDefault==1,
CustomCount);

CTestSt ts = (CTestSt)Marshal.PtrToStructure(pts, typeof(CTestSt));

//......
for(int k=0; k<ReturnResultCount; k++)
{
CRecordData rd=(CRecordData)Marshal.PtrToStructure( ts.RD[k],
typeof( CRecordData));
//...действия

//..уничтожение структуры
Marshal.DestroyStructure( ts.RD[k], typeof( CRecordData));
}
//..уничтожение структуры
Marshal.DestroyStructure(pts, typeof(CTestSt));

Код работает но класс CTestSt не уничтожается в результате имеем memory leak.
Кто подскажет как правильно уничтожать объект после использования???
Re: Утечка памяти при работе с С++ dll
От: mihailik Украина  
Дата: 13.01.06 15:56
Оценка:
K>У меня следующая проблема. Есть dll написаная на VC++ 6.0. которая экспортируют функцию:

K>extern "C" _declspec(dllexport)

K>#$@4%@#$@$@#$... @#$@... @#$$%#...

Слишком большой листинг, вообще-то. Трудно читать

А по существу — лучше подобные нетривиальные взаимодействия с неуправляемым кодом производить в Managed C++ Extensions.

В языке и практике использования C++ столько разных тонкостей, касающихся выделения памяти, а в среде .NET Framework многих аналогов нет. Специально для "подружения" этих антагонистов и предназначен MC++.
Re[2]: Утечка памяти при работе с С++ dll
От: kerimovmv  
Дата: 13.01.06 18:01
Оценка:
Здравствуйте, mihailik, Вы писали:

K>>У меня следующая проблема. Есть dll написаная на VC++ 6.0. которая экспортируют функцию:


K>>extern "C" _declspec(dllexport)

K>>#$@4%@#$@$@#$... @#$@... @#$$%#...

M>Слишком большой листинг, вообще-то. Трудно читать


M>А по существу — лучше подобные нетривиальные взаимодействия с неуправляемым кодом производить в Managed C++ Extensions.


M>В языке и практике использования C++ столько разных тонкостей, касающихся выделения памяти, а в среде .NET Framework многих аналогов нет. Специально для "подружения" этих антагонистов и предназначен MC++.


Это очень малый фрагмент кода на самом деле.
Если проще мне нужно вызвать а затем уничтожить (из C#) С++ структуру типа (TestSt*):

typedef struct stRecordData_tag
{
int DocWeight; // Document weight
char* Title; // Document title
char* DocKey; // Document key
char* BestSentences; // Document summary
}RecordData;

typedef struct stTestSt
{
RecordData* RD[1000];
int MaximumCount;
int ReturnCount;
char * Error;
}
TestSt;

Это структуру (вернее указатель на неё) (TestSt*) возвращает моя функция в C++....
То что рекомендует MSDN почему-то не работает в полной мере (или я использую это неверно???)...
Re[3]: Утечка памяти при работе с С++ dll
От: Mab Россия http://shade.msu.ru/~mab
Дата: 13.01.06 18:17
Оценка:
Пожалуйста, пользуйтесь тегами форматирования кода. Без них читать очень сложно.

K>Это структуру (вернее указатель на неё) (TestSt*) возвращает моя функция в C++....

K>То что рекомендует MSDN почему-то не работает в полной мере (или я использую это неверно???)...
Интересно, где в MSDN есть рекомендации освобождать память, выделнную в сторонней бибилиотеке через DestroyStructure? Данная функция предназначена для работы в паре с StructureToPtr, не более того. Вам же нужно продумать интерфейс освобождения самостоятельно. Есть два варианта:
1) либо unmanaged код будет экспортировать функцию освобождения
2) либо он должен пользовать станадартными средствами типа CoTaskMemAlloc, CoTaskMemFree.
Re[3]: Утечка памяти при работе с С++ dll
От: mihailik Украина  
Дата: 13.01.06 18:19
Оценка:
K>Если проще мне нужно вызвать а затем уничтожить (из C#) С++ структуру типа (TestSt*):

Я не знаю деталей, как компилятор C++ управляет памятью. А ведь для "уничтожения" нужно как минимум память освободить. Не говоря уж о возможных деструкторах.

Кстати, внутри структуры есть ещё и указатели char*. Соответственно, встаёт вопрос об их освобождении.


Различия между управляемым (C#) и неуправляемым (C++) кодом во многом коренятся именно в разной работе с памятью. Так что не факт, что тебе вообще удастся их подружить даже для этого отдельного случая. Лучше использовать MC++, там этой "дружбой" занимается сам Microsoft.
Re[4]: Утечка памяти при работе с С++ dll
От: kerimovmv  
Дата: 13.01.06 19:22
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Пожалуйста, пользуйтесь тегами форматирования кода. Без них читать очень сложно.


K>>Это структуру (вернее указатель на неё) (TestSt*) возвращает моя функция в C++....

K>>То что рекомендует MSDN почему-то не работает в полной мере (или я использую это неверно???)...
Mab>Интересно, где в MSDN есть рекомендации освобождать память, выделнную в сторонней бибилиотеке через DestroyStructure? Данная функция предназначена для работы в паре с StructureToPtr, не более того. Вам же нужно продумать интерфейс освобождения самостоятельно. Есть два варианта:
Mab>1) либо unmanaged код будет экспортировать функцию освобождения
Mab>2) либо он должен пользовать станадартными средствами типа CoTaskMemAlloc, CoTaskMemFree.

А можете примерчик простой дать как какой-нибудь из этих методов использовать.
Я пробовал FreeCoTaskMem — но он тоже не лечит...
Re[5]: Утечка памяти при работе с С++ dll
От: Mab Россия http://shade.msu.ru/~mab
Дата: 13.01.06 19:24
Оценка:
Здравствуйте, kerimovmv, Вы писали:

K>А можете примерчик простой дать как какой-нибудь из этих методов использовать.

K>Я пробовал FreeCoTaskMem — но он тоже не лечит...
Честно говоря, писать готовый пример нет времени. Казалось бы, все и так довольно подробно расписано. Если есть конкретные вопросы -- задавайте.
Re[6]: Утечка памяти при работе с С++ dll
От: kerimovmv  
Дата: 13.01.06 19:34
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Здравствуйте, kerimovmv, Вы писали:


K>>А можете примерчик простой дать как какой-нибудь из этих методов использовать.

K>>Я пробовал FreeCoTaskMem — но он тоже не лечит...
Mab>Честно говоря, писать готовый пример нет времени. Казалось бы, все и так довольно подробно расписано. Если есть конкретные вопросы -- задавайте.

Ну если нет времени дайте линк хотя бы.
Как интерфейс свой передавать из C++ в C#.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.