![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| Competitor |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 440 Регистрация: 23.3.2005 Где: Tula Репутация: -1 Всего: -1 |
Привет всем.
Сделал dll'ку на С++, которая работает с WMI и выдает на выход какую-то строку типа BSTR. Я импортирую эту дллку с свой основной проект на C#. Как мне передать значение из С++ дллки в C#, чтобы там оно нормально прочиталось. Допустим метод в С++ на экспорт выглядит так: Выделить всёкод C++
А в C# метод импорта выглядит так: Выделить всёкод C#
При таком написании вываливается ошибка записи в память. Подскажите плиз как решить эту проблему? |
||||
|
|||||
| Stepan_Lameroff |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 164 Регистрация: 16.12.2006 Репутация: 9 Всего: 14 |
А так не пробовали?
|
|||
|
||||
| snav |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 55 Регистрация: 8.9.2007 Репутация: 2 Всего: 4 |
Competitor,
Скорее всего, ошибка в неправильном декларировании возвращаемого значение на C#. Это связано с особенностями управления памятью при маршалинге. Дело в том, что существует несколько стратегий работы памятью при возврате указателя на строку. Различие состоит в том, кто отвечает за освобождение выделенной памяти и как должно осуществляться освобождение памяти. В твоем примере импортируемая функция объявлена следующим образом: [DllImport("Test1.dll")] public static extern string GetData(); При таком объявлении маршалер .NET использует стратегию, принятую в COM. Т.е. считается, что импортируемая функция DLL выделяет память, а приложение .NET должно ее освободить. Поэтому маршалер, получив указатель на строку BSTR, копирует строку в string, а затем пытается освободить память указателя, вызвав функцию CoTaskMemFree(). Видимо, из-за этого и происходит ошибка. Скорее всего, в твоей DLL применяется подход, подразумевающий, что приложение .NET не должно освобождать память, захваченную для указателя. В этом случае объявление функции должно быть следующим: [DllImport("Test1.dll")] private static extern IntPtr GetData(); Полученный таким образом указатель нужно вручную преобразовать в string, например: public static string GetDataEx() { IntPtr ptr = GetData(); if ( ptr == IntPtr.Zero ) return string.Empty; return Marshal.PtrToStringBSTR(ptr); } Возможно, что вместо метода Marshal.PtrToStringBSTR() тебе нужен другой метод типа Marshal.PtrToStringXXXX() в зависимости от того, какой указатель ты возвращаешь. Более подробно можно почитать в MSDN: http://msdn.microsoft.com/library/rus/defa...ymanagement.asp Это сообщение отредактировал(а) snav - 9.9.2007, 09:28 |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |