Native code .dll blocking c# form

I finally decided I couldn’t live with having my c# code getting blocked by garbage collection and went to offload my logic code into a native code .dll. I used the __declspec(dllexport) for my functions to make them visible from the .dll and did manage to call them from my c# code. One thing I can’t figure out is when I start a continuous thread in my native code, it blocks the form from which I call it from.
This is the example code for my .dll file

#include <windows.h>
#include <stdio.h>
#include "gpio.h"
 
HANDLE hGpio; //handle for the gpio
BOOL runLEDflash = FALSE;
HANDLE hToggle96;


extern __declspec(dllexport) BOOL runLED(DWORD interval)
{

uIo pin96 = COLIBRI_PIN(96);
BOOL ledState;
BOOL success;

	    // === Initialize GPIO library. ===
    // We don't use registry-based  configuration, thus we can 
    // pass NULL go Gpio_Init()
    hGpio = Gpio_Init(NULL);   
    ASSERT(hGpio != 0);
    success = Gpio_Open(hGpio);
    ASSERT (success);
 
    // === Io Manipulation ===
    // Configure the pin to act as GPIO (as opposed to an Alternate function)
    // Set it to Output,  High
    Gpio_ConfigureAsGpio(hGpio, pin96);
    Gpio_SetDir         (hGpio, pin96, ioOutput);

runLEDflash = TRUE;
while(runLEDflash){
if (ledState == 0)
            {
                ledState = 1;
                Gpio_SetLevel(hGpio, pin96, ioHigh);
            }
            else
            {
                ledState = 0;
                Gpio_SetLevel(hGpio, pin96, ioLow);
            }

Sleep(interval);
}
return 0;
}


extern __declspec(dllexport) void runThread(void)
{
	DWORD ThreadID;
hToggle96 = CreateThread (NULL, 0, runLED(50), 0, 0, &ThreadID);
//printf("Thread Started!");  //this never gets a chance to run!
return 1;
}

extern __declspec(dllexport) void killLED(void)
{
	runLEDflash = FALSE;
	return 1;
}

And this is how I call it from my c# form.

        [System.Runtime.InteropServices.DllImport("dllcreationtest.dll")]
        static extern void killLED();

        [System.Runtime.InteropServices.DllImport("dllcreationtest.dll")]
        static extern void runThread();

private void button1_Click(object sender, EventArgs e)
        {
            runThread(); //this should create a thead in the native code and run it indefinitely
            MessageBox.Show("this code never executes because runThread blocks it");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            killLED(); //this should kill my logic thread if needed
        }

I originally called the runLED function, but after that blocked, I decided I needed to create a thread that would run that particular function, yet the runThead function blocks as well! I’m clueless as to how the .dll is interfaced with my c# to make it block everything.

Any help or sugguestions are greatly appreciated. I’m hoping I can built this up to where I can send a class for the data configuration from c# (if that’s possible) so that all my logic code will run as native code at a high priority, and will pass off the results back to the c# code which handles all the ethernet, SD, and interface functions.

Thanks!
Matt

Dear @mdeiss,

Thank you for contacting support with details.

The following statement would be wrong

hToggle96 = CreateThread (NULL, 0, runLED(50), 0, 0, &ThreadID);

it must be

DWORD interval = 50;
hToggle96 = CreateThread (NULL, 0, runLED, &interval, 0, &ThreadID);

BOOL runLED(LPVOID pParam)
{
DWORD interval = *(DWORD *)pParam;
....
}

Please refer below links for more information.
https://docs.microsoft.com/en-us/previous-versions/ms939170(v%3Dmsdn.10)

http://geekswithblogs.net/BruceEitman/archive/2009/01/21/windows-ce-threads.aspx

Let us know if it doesn’t help. Thank you.

Thanks @raja.tx !

It worked perfectly!

Do you happen to have any suggestions for sharing configuration data across from c# to the native code?
I currently have a configuration class in c# filled with a giant mix of variables and it’d be nice to just push those variables to the native code, then have the native code operate accordingly to the data, and even communicate back to c#.

Is it possible to declare global variables in the native code that I can receive from c#? And, will the logic thread (hToggle96 ) in the example above, be able to touch and react to those variables getting changed?

Thanks again!
Matt

Dear @mdeiss,

We have a Dot net demo application in our Toradex CE libraries (…\libDemos\dotNet). Could you refer there to get sample cod e.g. CANDemo project?