Writting plug-in iin C-sharp

Hi. I finally pushing myself in writting plug-in for Enttec 's OpenDmx inside the dynamic plug-in editor structure.
It will be a good exercice for this very first steps.

I would like to know:
-where to put the FTD2XX DLL: beside VVVV or in plug in folder ?
-if i can merge inside VVVV namespace the OpenDMX classes furnished by Enttec here

any suggestion will be listen carefully ( for once) and with big amens from the head.

  1. Put it to there same folder where placed compiled plugin binary. Visual Studio will do it for you.
  2. Can’t understand your question. In usual way you just need to add external to VS and import classes by using keyword. Every library will have it’s own namespace.

hi alg ! thxs for your reply !
I m completely new to Csharp and somehow prehistoric.

To discuss with Enttec Open, i need to communicate with its own dll (FTD2XX.dll), passing it args. So i have classes with an import of its functions in an opendmx namespace.

In C i would have to link to the .lib, in order to communicate with the dll. Nothing like this in C Sharp ?

As i understand, you already have c# wrapper for FTD2XX.dll? So, you just need to use compiled version of this wrapper as reference in Visual Studio. Yes FTD2XX.DLL must be placed in the same dirrectory with compiled wrapper dll. “namespace Test” is not good namespace for wrapper class, just change it to something like “enttec.dmx”.

Ok. So i can t do this inside vvvv? About wrapper you mean a .lib or .a ?

the enttec seems to be a unmanaged .dll, this is something very different from a .NET managed dll…

you access a managed .dll with DllImport in a class. the class could be anywhere in your project. so just copy this code into your plugin (inside the namespace):

code(lang=csharp):
public class OpenDMX

{

    public static byte[]() buffer = new byte[511](511);
    public static uint handle;
    public static bool done = false;
    public static int bytesWritten = 0;
    public static FT_STATUS status;

    public const byte BITS_8 = 8;
    public const byte STOP_BITS_2 = 2;
    public const byte PARITY_NONE = 0;
    public const UInt16 FLOW_NONE = 0;
    public const byte PURGE_RX = 1;
    public const byte PURGE_TX = 2;


    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_Open(UInt32 uiPort, ref uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_Close(uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_Read(uint ftHandle, IntPtr lpBuffer, UInt32 dwBytesToRead, ref UInt32 lpdwBytesReturned);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_Write(uint ftHandle, IntPtr lpBuffer, UInt32 dwBytesToRead, ref UInt32 lpdwBytesWritten);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_SetDataCharacteristics(uint ftHandle, byte uWordLength, byte uStopBits, byte uParity);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_SetFlowControl(uint ftHandle, char usFlowControl, byte uXon, byte uXoff);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_GetModemStatus(uint ftHandle, ref UInt32 lpdwModemStatus);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_Purge(uint ftHandle, UInt32 dwMask);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_ClrRts(uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_SetBreakOn(uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_SetBreakOff(uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_GetStatus(uint ftHandle, ref UInt32 lpdwAmountInRxQueue, ref UInt32 lpdwAmountInTxQueue, ref UInt32 lpdwEventStatus);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_ResetDevice(uint ftHandle);
    [DllImport("FTD2XX.dll")](DllImport("FTD2XX.dll"))
    public static extern FT_STATUS FT_SetDivisor(uint ftHandle, char usDivisor);


    public static void start()
    {
        handle = 0;
        status = FT_Open(0, ref handle);
        Thread thread = new Thread(new ThreadStart(writeData));            
        thread.Start();
        setDmxValue(0, 0);  //Set DMX Start Code
    }

    public static void setDmxValue(int channel, byte value)
    {
        if (buffer != null)
        {
            buffer[channel](channel) = value;
        }
    }

    public static void writeData()
    {
        while (!done)
        {
            initOpenDMX();
            FT_SetBreakOn(handle);
            FT_SetBreakOff(handle);
            bytesWritten = write(handle, buffer, buffer.Length);
            Thread.Sleep(25);
        }

    }

    public static int write(uint handle, byte[]() data, int length)

{
IntPtr ptr = Marshal.AllocHGlobal((int)length);
Marshal.Copy(data, 0, ptr, (int)length);
uint bytesWritten = 0;
status = FT_Write(handle, ptr, (uint)length, ref bytesWritten);
return (int)bytesWritten;
}

    public static void initOpenDMX()
    {
        status = FT_ResetDevice(handle);
        status = FT_SetDivisor(handle, (char)12);  // set baud rate
        status = FT_SetDataCharacteristics(handle, BITS_8, STOP_BITS_2, PARITY_NONE);
        status = FT_SetFlowControl(handle, (char)FLOW_NONE, 0, 0);
        status = FT_ClrRts(handle);
        status = FT_Purge(handle, PURGE_TX);
        status = FT_Purge(handle, PURGE_RX);
    }

}

/// <summary>
/// Enumaration containing the varios return status for the DLL functions.
/// </summary>
public enum FT_STATUS
{
    FT_OK = 0,
    FT_INVALID_HANDLE,
    FT_DEVICE_NOT_FOUND,
    FT_DEVICE_NOT_OPENED,
    FT_IO_ERROR,
    FT_INSUFFICIENT_RESOURCES,
    FT_INVALID_PARAMETER,
    FT_INVALID_BAUD_RATE,
    FT_DEVICE_NOT_OPENED_FOR_ERASE,
    FT_DEVICE_NOT_OPENED_FOR_WRITE,
    FT_FAILED_TO_WRITE_DEVICE,
    FT_EEPROM_READ_FAILED,
    FT_EEPROM_WRITE_FAILED,
    FT_EEPROM_ERASE_FAILED,
    FT_EEPROM_NOT_PRESENT,
    FT_EEPROM_NOT_PROGRAMMED,
    FT_INVALID_ARGS,
    FT_OTHER_ERROR
};

then add the missing uses clause on top:

code(lang=csharp):
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;

and yes, in order to find the dll, it must lie besides the calling .exe, which is vvvv.exe in your case. if that doesn’t work try the bin/managed folder…

hi tonfilm, many thanks !
So i was ok in my config and placement of code and dll.
We agree i can do it inside the vvvv code editor ?
or i didn’t understood ?

as i m not at all used to C#, how can i do an output of enum status inside the TTY ( to debug and know exactly were is my problem ) ? aka something like a sprintf function ?

FLogger.Log(LogType.Debug, "message");

or something like that

yeah, know it, put what is the equivalent to sprintf function:

bool is_ignited;
char my_feedback[256](256)
sprintf(my_feedback, "Interface is open %d, status %d", is_ignited, status);

cheers

Try

String.Format("format string", parameters);

found via google: http://bytes.com/topic/c-sharp/answers/236777-printf-format-c

;-)

debugging is easier with sharpdevelop. while coding in vvvv you can set the build mode to debug in the project explorer (ctrl+j). then open the .csproj of your plugin with sharpdevelop and select debug->attach to process->vvvv.exe. then you can do breakpoints in your code and inspect the values of the code.

many thanks for link and advices! I will see this sharp developp thing
On touring actually, will go back to thsi question in one week , no dimmers in hotel !

@tonfilm, can i use latest SharpDevelop 4? Or must use 3.2?

should work with 4.0… but i used 3.2, as far as i remember.
vvvv should run with the plugin of course, and only code in the vvvv code editor… use sharpdevelop only for debugging.

Tested SD 4.0 yesterday - works fine. Big thx for this workflow advice. Previously i’m used VS 2010 for debugging, but it takes so much time to load and always converts project.