Не знаю, какая религия запрещает сделать это в одном вызове при помощи out параметра (ссылки на указатель или указателя на указатель).
так заранее размер неизвестен. Сколько выделять в шарпе памяти, если ещё не вызвал процедуру, я не знаю
Кто же знает, в твоём dispose ничего не написано. Могу предположить, что ты, получив массив из DLL, далее, вместо того, чтобы скопировать его в managed-память и избавиться от указателей, продолжаешь его злостно использовать в unmanaged-памяти из managed-кода.
нее, я не такой
)
UINT32 WINAPI GetGifArray(UINT8* pArray, UINT32 ArrayLen)
{
UINT32 toCopy=min(CGF.gifFile.size(),ArrayLen);
if(toCopy)
{
::memmove(pArray,&CGF.gifFile[0],toCopy);
}
return toCopy;
}
а в шарпе я больше не использую нигде. Показанный код на C# - это весь код проекта (не включая визардовский)
Добавлено через 47 секунд:Ещё один любопытный вопрос - зачем было городить DLL на C++ для работы с GIF, когда в .NET есть встроенные средства?
так надо заказчику. Вот именно так. Я даже спрашивал - может сразу на диск сохранять файл ? - нее, надо именно массив в шарп передать
Добавлено через 1 час, 10 минут и 17 секунд:Дим, глянь, если не сложно, что там у меня не так...
Вот проект, DLL в папке bin/debug уже лежит, версия - релизная
Добавлено через 13 минут и 58 секунд:если забить обе строчки с вызовам функций из длл, то не вылетает. Что-то в этом моменте я не так сделал. Если открыть даже только строчку с GenerateGIF_v1 - начинается
Добавлено через 1 час, 27 минут и 48 секунд:Поменял содержимое функций следующим образом (чтобы было точно видно, что в самой DLL происходит):
DLL (собрана в релизе)
//массив с гифом - глобальный.
//вызов GenerateGIF_v1 заполняет его и возвращает размеры
//вызов GetGifArray заполняет внешний буфер
std::vector<BYTE> gifFile;
UINT32 WINAPI GenerateGIF_v1
(
UINT32 _letters_H//высота кегля
,UINT32 _delay_ms//задержка в мс (реально воспринимаются значения, кратные 10 мс)
,const WCHAR* pwch_text//текст
,const WCHAR* pwch_fontName//имя шрифта
)
{
gifFile.resize(100);
return gifFile.size();
}
UINT32 WINAPI GetGifArray(UINT8* pArray, UINT32 ArrayLen)
{
UINT32 toCopy=min(gifFile.size(),ArrayLen);
if(toCopy)
{
::memmove(pArray,&gifFile[0],toCopy);
}
return toCopy;
}
содержимое класса в C# программе:
public partial class Form1:Form
{
[DllImport("GifGenerator.dll")]
static extern UInt32 GenerateGIF_v1( UInt32 _letters_H,UInt32 _delay_ms,IntPtr pwch_text,IntPtr pwch_fontName);
[DllImport("GifGenerator.dll")]
static extern UInt32 GetGifArray( IntPtr pArray,UInt32 ArrayLen);
private void button1_Click(object sender,EventArgs e)
{
//генерируем гифку
UInt32 gif_len=0;
byte[] gif_array=null;
{
//zero-term в конце строк добавлять обязательно!
//иначе строки при маршалинге не будут ограничены нулём
string text="12345\0";
string font="Times New Roman\0";
char[] p_text = text.ToCharArray();
char[] p_font = font.ToCharArray();
int text_len=p_text.Length;
int font_len=p_font.Length;
IntPtr marsh_text = Marshal.AllocHGlobal(text_len);
IntPtr marsh_font = Marshal.AllocHGlobal(font_len);
{
//подготавливаем текст для передачи
Marshal.Copy(p_text,0,marsh_text,text_len);
Marshal.Copy(p_font,0,marsh_font,font_len);
gif_len=GenerateGIF_v1(40,60,marsh_text,marsh_font); //<<<<<<<<<<<<<<<<<<< это проблемная строчка!
}
Marshal.FreeHGlobal(marsh_text);
Marshal.FreeHGlobal(marsh_font);
}
}
}
Запускаем программу, жмём кнопку . Потом закрываем программу.
если закомментить проблемную строчку - всё нормально. Если открыть - вылетает ошибка после закрытия программы , запущенной в дебаге
(проект и DLL приложены)