Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

объясните некорректное поведение программы

17K
24 января 2013 года
Suleyman
12 / / 15.06.2008
В программе на С# хочу задействовать dll скомпилированную с ключом gnu99 с помощью MinGW написаную на С. В данной библиотеке импортируется функция, которая запускает отдельный поток. Функция потока вызывает делегат переданный с помощью параметра.

Код dll

Код:
typedef void (*pf)(void);

typedef struct{
    uint8_t flgStop;
    pf funcDelegate;
}Info;


uintptr_t hThread;
DWORD dwThreadID;

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * запуск выделенного потока
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

uint8_t InitThread(Info* str){

    hThread = _beginthread(ThreadProc, 0, str);

    return 0;
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * метод потока
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//DWORD WINAPI ThreadProc( LPVOID lpParam ){
void ThreadProc(void* lpParam ){

    const Info* const is = (Info*)lpParam;

    while(!is->flgStop){

        if(is->funcDelegate != NULL){
            (*(is->funcDelegate))();
        }
        Sleep(1);

    }

    char txt[25];
    sprintf(txt, "Флаг стоп = %d", is->flgStop);
    MessageBox(0, txt, "Сообщение", MB_OK);

}


В проэкте на C# я импортирую ф-ю InitThread


Код:
namespace Test
{
    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    internal struct nativeThreadParams
    {
        internal byte flgStop;
        internal IntPtr deleg;
    }


    public delegate void FuncDelegate();


    public partial class Form1 : Form
    {
        [DllImport("libtestDelegateToNative.dll",CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.U1)]
        internal extern static byte InitThread(ref nativeThreadParams param);

        internal nativeThreadParams paramsThread;

        static public FuncDelegate del;
        private static int valTest1, valTest2;

        public Form1()
        {
            InitializeComponent();
            del += this.Test1;
            paramsThread.deleg = Marshal.GetFunctionPointerForDelegate(del);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            paramsThread.flgStop = 0;
            if (InitThread(ref paramsThread) != 0)
            {
                MessageBox.Show("Не удалось запустить тестовый поток");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.paramsThread.flgStop = 1;
        }

        public void Test1()
        {
            valTest1++;
            if (textBox1.InvokeRequired)
                textBox1.Invoke(new Action<string>((s) => textBox1.Text = s), valTest1.ToString());
        }

    }
}
При нажатии кнопки вызывается обработчик "button1_Click" который вызывает импортированную функцию из dll.

Некорректность работы программы заключается в том что при вызове "buttonClick" происходит запуск нового потока и он вызывает переданный делегат - но после нескольких сотен вызовов происходит завершение потока как будто я передал флаг завершения потока. Если ещё раз вызвать "buttonClick" то поток вновь запускается и уже работает без самостоятельного завершения. Такое ощущение что происходит порча памяти из-за неправильного импорта функции или неправильно переданых параметров и это происходит только при первом вызове функции из dll, а потом всё работает как надо. Объясните пожалуйста почему так может происходить.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог