объясните некорректное поведение программы
Код 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);
}
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());
}
}
}
{
[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());
}
}
}
Некорректность работы программы заключается в том что при вызове "buttonClick" происходит запуск нового потока и он вызывает переданный делегат - но после нескольких сотен вызовов происходит завершение потока как будто я передал флаг завершения потока. Если ещё раз вызвать "buttonClick" то поток вновь запускается и уже работает без самостоятельного завершения. Такое ощущение что происходит порча памяти из-за неправильного импорта функции или неправильно переданых параметров и это происходит только при первом вызове функции из dll, а потом всё работает как надо. Объясните пожалуйста почему так может происходить.