Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов функций из dll для изменения компонентов 
:(
    Опции темы
kiler4747
Дата 1.6.2011, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.2.2011

Репутация: нет
Всего: нет



Написал программу для копирования папки на C#, а сейчас решил написать сами функции на C++(dll) и сделать многопоточной, но возникает ошибка входе в функцию из dll, проверял вызов функции в С++ - все нормально. Хочу запустить сначала фоновый поток для поиска количества файлов и увеличивать каждый раз maximum в progressBar(bar) и сразу запустить поток для копирования.

Код

...
class MyClass
{
    ProgressBar bar;
    string folderout{get; set;}
    string folderin{get; set; }

    MyClass(ProgressBar bar1)
    {
        bar = bar1;
    }
    ...
    public void runcopy(string outl, string inl)
            {
                folderout = outl;
                folderin = inl;
                Thread thr = new Thread(UpdateProgressMax);
                thr.IsBackground = true;
                thr.Start();
                CopyFolder(outl + "\\", inl + "\\");
            }

    [DllImport("Exploer_03(dll).dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            extern static void MaxValueWchar(string outl,ref long maxbar);

            void UpdateProgressMax()
            {
                long barr = bar.Maximum;
                bar.Invoke(new MethodInvoker(delegate { MaxValueWchar(folderout, out barr); }));
            }
    ...
}


dll(C++)
Код

extern "C" _declspec(dllexport) void MaxValue(CString Path, long *maximum)
{
    if (Path[Path.GetLength()] != L'\\')
        Path += L'\\';
    HANDLE handle;
    WIN32_FIND_DATA data;
    handle = FindFirstFile(Path + L"*.*",&data);
    do 
    {
        if (handle == INVALID_HANDLE_VALUE)
            break;
        if (data.cFileName[0] == L'.')
            continue;
        if ( (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
        {
            MaxValue(Path + data.cFileName, maximum);
        }
        else
            (*maximum)++;
    } while (FindNextFile(handle,&data) != 0);
}

void MaxValueWchar(wchar_t * path, long * lg)
{
    CString Path = path;
    MaxValue(Path, lg);
}


Добавлено через 54 секунды
Что неправильно?
PM MAIL Skype   Вверх
jonie
Дата 1.6.2011, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



давно ли CString стал мапиться на string из C# ? 
мапиться могут только относительно несложный типы, например const TCHAR*, CString тут не прокатит
Цитата

Код

extern "C" _declspec(dllexport) void MaxValue(CString Path, long *maximum)



а, если речь про MaxValueWchar - тогда она вообще из DLL нигде  (по этому коду) не экспортируется.. да и называться она, скорее всего, будет _MaxValueWchar ..

Это сообщение отредактировал(а) jonie - 1.6.2011, 22:26


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
kiler4747
Дата 1.6.2011, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.2.2011

Репутация: нет
Всего: нет



Согласен что CString несовместим с string(C#), поэтому и писал вторую функцию с wchar_t(C++ знаю не очень).
MaxValueWchar, у меня в программе правильно написано, сюда не все скопировал. Когда и почему функции из dll надо вызывать с добавлением _ , раньше писал без _ и все работало, хотя когда спрашивал насчет вызова функций писали что скорее всего функция должна начинаться с _.
Код

extern "C" _declspec(dllexport) void MaxValueWchar(wchar_t * path, long * lg)
{
    CString Path = path;
    MaxValue(Path, lg);
}


Ошибка возникает при входе в функцию из dll:
File: f:\dd\vctools\vc7libs\ship\atlmfc\include\atlsimpstr.h
Line: 393
Expression: (iChar >= 0) && (iChar <= GetLength())



Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  Synth.rar 209,30 Kb
PM MAIL Skype   Вверх
kiler4747
  Дата 3.6.2011, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.2.2011

Репутация: нет
Всего: нет



Разобрался почему не работали функции - не ту функцию вызывал. Но основная проблема осталась: Как из dll(C++) изменить в ProgressBar свойства Value и Maximum?

Код

...
string folderout{get; set;}
string folderin{get; set; }
...
//функция для подсчета файлов

extern static void MaxValue(string outl,ref long maxbar);
            [DllImport("Exploer_03(dll).dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            extern static void MaxValueWchar(string outl,ref int maxbar);

            void UpdateProgressMax()
            {
                int barr = bar.Maximum;
                MaxValueWchar(folderout, ref barr);
                bar.Invoke(new MethodInvoker(delegate { bar.Maximum = barr; }));
            }

//функция для копирования папки

[DllImport("Exploer_03(dll).dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            extern static void copyd(string outl, string inl, ref int lg);
void copyfromdll()
            {
                int lg = 0;
                bar.Invoke(new MethodInvoker(delegate { bar.Value = lg; }));
                copyd(folderout, folderin, ref lg);
                MessageBox.Show("End");
            }

//создание потоков для копирования

public void runcopy(string outl, string inl)
            {
                folderout = outl + "\\";
                folderin = inl + "\\";
                Thread thr = new Thread(UpdateProgressMax);
                thr.IsBackground = true;
                thr.Start();
                bar.Invalidate();
                Thread thr1 = new Thread(copyfromdll);
                thr1.Start();
            }


функции из dll(C++)
Код

extern "C" _declspec(dllexport) void CopyFolder( CString sours,  CString dest, long * num)
{
    HANDLE result;
    WIN32_FIND_DATA data;
    if (sours[sours.GetLength() - 1] != L'\\')
        sours += L'\\';
    if (dest[dest.GetLength() - 1] != L'\\')
        dest += L'\\';
    result = FindFirstFileEx(sours + L"*.*",FindExInfoBasic, &data,FindExSearchNameMatch,NULL,0);
    do 
    {
        if (result == INVALID_HANDLE_VALUE)
            break;
        if (data.cFileName[0] == L'.')
            continue;
        if ( (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
        {
            HANDLE handle;
            handle = FindFirstFileW(dest + data.cFileName, new WIN32_FIND_DATA() );
            if (handle == INVALID_HANDLE_VALUE)
                CreateDirectory(dest + data.cFileName,NULL);
            CopyFolder(sours + data.cFileName, dest + data.cFileName, num);
        }
        else
        {
            HANDLE handle;
            WIN32_FIND_DATA date;
            handle = FindFirstFileW(dest + data.cFileName, &date);
            if (handle == INVALID_HANDLE_VALUE)
                CopyFileW(sours + data.cFileName,dest + data.cFileName,false);
            else
                if (date.ftLastWriteTime.dwHighDateTime > 
                    data.ftLastWriteTime.dwHighDateTime)
                    CopyFileW(sours + data.cFileName,dest + data.cFileName,true);
            wchar_t *ti = data.cFileName;
            (*num)++;
        }
    } while (FindNextFileW(result,&data) != 0);
    FindClose(result);
}

extern "C" _declspec(dllexport) void MaxValue(CString Path, long *maximum)
{
    if (Path[Path.GetLength()] != L'\\')
        Path += L'\\';
    HANDLE handle;
    WIN32_FIND_DATA data;
    handle = FindFirstFile(Path + L"*.*",&data);
    do 
    {
        if (handle == INVALID_HANDLE_VALUE)
            break;
        if (data.cFileName[0] == L'.')
            continue;
        if ( (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
        {
            MaxValue(Path + data.cFileName, maximum);
        }
        else
            (*maximum)++;
    } while (FindNextFile(handle,&data) != 0);
}

extern "C" _declspec(dllexport) void MaxValueWchar(wchar_t * path, long * lg)
{
    CString Path = path;
    MaxValue(Path, lg);
}

extern "C" _declspec(dllexport) void copyd(const wchar_t *str1,const wchar_t *str2, long * num)
{
    CString st1 = str1;
    CString st2 = str2;
    CopyFolder(st1,st2, num);
}


PM MAIL Skype   Вверх
jonie
Дата 3.6.2011, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



вам надо каллбэк. Я накатал пример (в аттаче) с вызовом калбэка. но использовать его надо крайне осторожно: я не весьма уверен что сам создаваемый делегат не надо сохранять в GC (есть такой метод GCHandle.Alloc - это надо изучать).


Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  CppCsharpCallback.rar 5,34 Kb


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0852 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.