powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача данных C# -> DLL С++ ->SQLite и обратно
25 сообщений из 58, страница 1 из 3
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39403049
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте уважаемые Гуру!

Сразу прошу вас не пинать больно, так как я новичок
Собственно не могу сообразить как передать в C#, полученный в dll на c++
набор записей из SQLite.

Использовать NET System.Data.SQLite для работы пожалуйста не предлагайте.

C# используется только для пользовательского интерфейса, а вся работа с базой (запросы)
осуществляется только в DLL на с++.

Параметры для DLL я передаю из C# и обратно строковые данные тоже могу получить.
А вот как можно передать из dll результирующий набор записей в C# (в виде объекта)
на подобии DataTable в .NET чтобы присвоить как sourse DataGridView (если таковое возможно)?

Или заполнять Grid построчно, но опять таки нужен полученные из dll объект (набор строк)

Направьте пожалуйста мысль в правильную сторону. Мое гугление пока без нужного результата.
Можно ли это сделать Маршалингом, если да, то подскажите как.
С маршалингом простых данных я разобрался.
А вот как со сложными структурами или объектами...?
Как их подготовить в С++ к передаче и в С# распаковать не могу понять.

Еще была мысль использовать JSON и передавать одной строкой.
Распаковать строку JSON в объект С# я распакую, а вот как запаковать объект
(набор записей) в строку JSON на стороне dll не нашел.
Библиотеки json для с# и С++ в наличии.
Вопрос корости работы такой связки пока не очень критичен, но желательно иметь в виду.

Может есть другие решения, если приведете кусочек кода буду счастлив безмерно!
Заранее благодарен откликнувшимся.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39403061
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArbitА вот как со сложными структурами или объектами...?
можно передать в c# XML, пригодный для прямой десериализации в dataset
Модератор: Отредактировано
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39403075
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, безмерно рад общению! :)

а "анально" - это как перевести?
Это как - "банально" или это как - через " *опу" :) Я шучу, просто рад встрече

А что лучше использовать в моем случае с точки зрения производительности, XML или jcon?
Я так понял что если - XML, то можно подключить как source к гриду,
а если - json, то только заполнить грид строками в цикле из объекта после распаковки json?
По скорости это не будет иметь значения?
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39403079
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Направьте пожалуйста мысль в правильную сторону

1. Читать учебники

2. Пока достаточно не прочитал, использовать стандартные средства работы с СУБД из C#

3. Не писать в С++ топик без оснований
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39403110
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, спасибо большое!
Как всегда, кратко и исчерпывающе!
Именно то что мне нужно.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39405089
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, доброго дня!

Изопропил можно передать в c# XML, пригодный для прямой десериализации в dataset
А можно сериализовать/десериализовать объект DataTable без помещения его предварительно в контейнер DataSet?
Я обычно сразу загружаю вот так, если всего одна таблица:
Код: c#
1.
2.
3.
var adapter = new OleDbDataAdapter(cmd);
var dataTable = new DataTable();
adapter.Fill(dataTable)


или без DataSet это не работает?
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39405310
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, Спасибо большое!!!
Все работает великолепно.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512497
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, Прошу заранее прощения за беспокойство!

Использовал XML для передачи набора строк из SQLite и все было хорошо, в DataTable все загружалось!
Любые данные!
Но это работало на очень маленьких наборах строк

Когда же понадобилось передать из С++ в С# данные из более чем 33-34 строк(в зависимости от количества полей)
Получаю пустой DataTable.

Это что, недостаточно памяти выделяется для DataTable?
Подскажите пожалуйста как можно решить эту задачу.
Может я не учел чего-то формируя XML в С++?
Или неправильно принимаю XML в С#?

Заранее благодарен за помощь!
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512503
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arbit, ты в ГитХабе есть?
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512508
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl,

Еще раз повторюсь.
Код рабочий. Данные любые отправляются и принимаются!!!
Проблема только в том, что если набор строк превышает предел (у меня это - 33 строки)
сериализованная строка не принимается из DLL Получаю исключение:
{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public static bool Select(string QueryName, ref DataTable dt, string WhereValues="")
        {
            //Вызываем библиотечную функцию (в параметре - имя запроса)
            try
            {
                string strXML = DLL_Select(QueryName, WhereValues, ref CountRows);
                //Десериализуем полученные данные
                strXML = Main.Base64DecodeString(strXML);
                //Заполняем DataTable полученными данными
                using(StringReader rd = new StringReader(strXML))
                {
                    dt = new DataTable();
                    dt.ReadXml(rd);
                    rd.Dispose();
                }
            }
            catch
            {
                return false;
            }
            
            return true;
        }
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512509
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton,
откуда мне там быть? :))
Я не профи, я просто люблю программирование
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512571
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Туда не нужен пропуск профи.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512933
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: Отредактировано
Нужен код DLL_Select - в ней не выделяется достаточно памяти
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512938
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl,
Да я понял что мало памяти.
В dll формирование XML строки проверил - все правильно
Сейчас сам попробую найти косяк с памятью.
Если не получится то побеспокою Вас

Спасибо за желание помочь
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512960
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl,

Я делал так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
extern "C" __declspec(dllexport) BSTR DLL_Select(const char* pQueryName, const char* pWhereValues, int  *CountRow)
{
        //Генерирую strXML (c этим все в порядке, строка правильная)
        //Перевожу ее в base64 и возвращаю:

	return _bstr_t(strXML.c_str());
}



В C# принимал так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
[DllImport(@"D:\ProjectsC#\FinStudio\Debug\FinStudioDLL.dll")]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static extern string DLL_Select(string QueryName, string WhereValues, ref int CountRows);

public static bool Select(string QueryName, ref DataTable dt, string WhereValues="")
        {
            //Вызываем библиотечную функцию (в параметре - имя запроса)
            try
            {
                string strXML = DLL_Select(QueryName, WhereValues, ref CountRows);
                //Десериализуем полученные данные
                strXML = Main.Base64DecodeString(strXML);
                //Заполняем DataTable полученными данными
                using(StringReader rd = new StringReader(strXML))
                {
                    dt.ReadXml(rd);
                    rd.Dispose();
                }
            }
            catch
            {
                return false;
            }
            
            return true;
        }


У меня есть подозрение, что в таком исполнении передачи строки, в памяти выделяется какой-то default размер
И все, что превышает - лезет в защищенную память.
Видимо нужно передавать строку, как байтовый массив и возвращать указатель на этот массив и размер его.
А в С# получать указатель как IntPtr и переводить массив в string
Или есть более правильное решение?
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512967
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arbit//Перевожу ее в base64 и возвращаю:

И возвращаешь указатель на уже освобождённую память.
Модератор: Отредактировано
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39512979
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
А нельзя ли чуть полегче, без цитат
И чуть подробнее

Я не профи и не студент, и вообще не технарь. Я из другого "цеха" я программирую мозги на любой "платформе".
А сейчас изучаю другое программирование и по ходу пишу свой маленький проектик.
Давайте дружить! :)

Приведенный код работает, но до определенного объема передаваемых данных
Если можете пролить свет, буду благодарен
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513001
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArbitЯ не профи и не студент, и вообще не технарь. Я из другого "цеха" я программирую мозги на
любой "платформе".

Ок, перевожу на лекарский: ты посылаешь сестру за пациентом с койки номер шесть. Но ты не
позаботился о том, чтобы этого пациента не трогали, поэтому он давно умер, был вскрыт,
расфасован на органы и частично кремирован. То, что тебе притащит сестра может быть куском
нужного пациента, а может быть и вообще левым пациентом, которому не повезло занять эту
койку гораздо позже. Если не повезёт, то там вообще не окажется этой койки, поскольку она
сгорела вместе с госпиталем.

А теперь таки начни изучать что такое компьютеры, как они работают, что такое память и как
ею следует управлять с тем, чтобы и койка была на месте и пациента не порезали до момента
как его к тебе привезут.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513011
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
Да...
А я к Вам ведь, батенька, на ВЫ,
И больше чем уверен, что вдвое если не больше старше Вас..

А ведь некоторое время назад я получил от Вас достаточно приличную для меня помощь
и, причем, без всяких понтов.
Я даже прилюдно выразил свою Особую благодарность Вам
и другим Вашим коллегам

Если бы у Уважаемого Изопропила была минутка свободного времени, он бы не писал так много букв,
Одно предложение - и решение вопроса было бы найдено. Достойный пример для подражания!

Ну да ладно, бог Вам судья
На этом закончим общение
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513036
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arbit..И больше чем уверен, что вдвое если не больше старше Вас..Эт врядли, столько пока не живут=)

В общем проблема в том, что твой strXML.c_str() уничтожен по выходу из функции, как локальная переменная.

Лучше передавай функции свой буфер нужного (с запасом размера), в который будет писаться результат.

С bstr тоже можно, но контролировать кто создает и освобождает ее память
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513039
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arbit, не переживай док! Поможем тебе. А все нехорожие и злые поциенты
будут прокапаны и проклизьмены и уложены спать.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513042
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglЛучше передавай функции свой буфер нужного (с запасом размера), в который будет писаться результат.
Пока помню, еще его надо залочить в памяти,чтобы GC не передвинул. Все в MSDN есть
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513079
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl,

SiemarglВ общем проблема в том, что твой strXML.c_str() уничтожен по выходу из функции, как локальная переменная.
Объясните пожалуйста "особоодаренному" почему:
не смотря на это я получаю в С# XML строку десериализую ее и гружу благополучно в grid?
Проблема только в том что при передаче строки длиной больше определенного значения вылетает исключение

Есть у меня еще вариант. Я передавал из dll не строку а байтовый массив изображения
Делал так (выделял и очищал память в C#)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
[DllImport(@"D:\ProjectsC#\FinStudio\Debug\FinStudio.dll")]
        public static extern IntPtr DLL_LoadImage(string pKeyBinary, ref int ArrSize);  

IntPtr pArrImg = DLL_LoadImage(KeyBinary, ref ArrSize);

        public static byte[] LoadImage(ref DataGridView dgv)
        {
            string KeyBinary = dgv.CurrentRow.Cells["KeyBinary"].Value.ToString();
            int ArrSize = 0;
            IntPtr pArrImg = DLL_LoadImage(KeyBinary, ref ArrSize);
            byte[] arrImg = new byte[ArrSize];
            try
            {
                Marshal.Copy(pArrImg, arrImg, 0, arrImg.Length);
            }
            catch
            {
                ...
            }
            finally
            {
                Marshal.FreeCoTaskMem(pArrImg);
            }

            return arrImg;
        }


В C++
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
extern "C" __declspec(dllexport) byte* DLL_LoadImage(const char* pKeyBinary, int *psize)
{
byte* pBuff; //Сюда грузил изображение

*psize  //размер буфера

	return  pBuff;
}


Можно пойти этим путем при передачи строки, но
теперь нужно перегнать string в байтовый массив и как быть с символом конца строки?
записывать его в массив или нет для передачи из DLL в С#?
И как лучше сделать это преобразование?

Массив будет большой там будет много данных для грида и памяти нужно будет много
и как я понял, по результатам гугления нужен непрерывный блок памяти

Что подскажите?

Спасибо!
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513103
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArbitОбъясните пожалуйста "особоодаренному" почему:
не смотря на это я получаю в С# XML строку десериализую ее и гружу благополучно в grid?
Проблема только в том что при передаче строки длиной больше определенного значения вылетает исключение
Тебе Сибиряков именно на этот вопрос и ответил, только на своем языке.
Ладно, переведу:
Освобожденная память локального объекта, в которой была полная правильная строка xml, все еще может полностью или частично принадлежать твоему процессу, и если повезет - даже с правильными не затертыми данными.
На маленьких размерах тебе везет (хотя дело не в везении, конечно, а в том, что менеджер памяти резервный буфер оставил в этом месте, плюс другие потоки не пишут (пока) туда).
Медсестра принесла часть трупа))

Сделай, например, так:
1. Выдели вручную память (под строку) в dll под эту строку (xml.c_str), скопируй в нее данные, ее и возвращай в c#
2. Сделай в dll функцию cpp_free с параметром - указатель на строку, в функции просто удаляй память
3. В c# после использования строки вызови cpp_free

Думаю, должно заработать, если шарп "не испортит (не передвинет) указатель", но тут я уже не разбираюсь.
...
Рейтинг: 0 / 0
Передача данных C# -> DLL С++ ->SQLite и обратно
    #39513349
Arbit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock, спасибо большое
YuRockОсвобожденная память локального объекта, в которой была полная правильная строка xml, все еще может полностью или частично принадлежать твоему процессу, и если повезет - даже с правильными не затертыми данными .
Все кратко и понятно!
Разве трудно было написать Сибирякову эти две строчи? Ан нет... ладно проехали
YuRock2. Сделай в dll функцию cpp_free с параметром - указатель на строку, в функции просто удаляй память
3. В c# после использования строки вызови cpp_free
Мне не хочется дважды обращаться к DLL - второй раз для очистки памяти.
Хочется за один раз
а если я сделаю как писал выше
C#
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
            IntPtr pArrImg = DLL_LoadImage(KeyBinary, ref ArrSize);
            byte[] arrImg = new byte[ArrSize];
            try
            {
                Marshal.Copy(pArrImg, arrImg, 0, arrImg.Length);
            }
            catch
            {
                ...
            }
            finally
            {
                Marshal.FreeCoTaskMem(pArrImg); //Освобожу память здесь по полученному указателю из DLL - это будет правильно??? 
            }



Спасибо.
...
Рейтинг: 0 / 0
25 сообщений из 58, страница 1 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача данных C# -> DLL С++ ->SQLite и обратно
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]