none
calling a __stdcall function pointer in a c# application RRS feed

  • Question

  • I have a c++ application(program.cpp ) and a .h file of  c++ dll. I want to call the dll functions from a c# application . The problem is to use the function pointers in  c#. Please help with this.

    /*Program.h*/

    #ifndef ess_cH
    #define ess_cH

    unsigned long long __stdcall ess_initialization(unsigned short serial);


    unsigned char __stdcall ess_close(unsigned long long handle);


    unsigned char __stdcall ess_get_serial(unsigned long long handle,
       unsigned short * serial,
                                           unsigned short * version);


    /*Program.cpp*/

    typedef unsigned long long(__stdcall *init)(int);
    typedef int(__stdcall *serial)(unsigned long long, unsigned short *, unsigned short *);
    typedef int(__stdcall *close)(unsigned long long);

    int main(int argc, char *argv[])
    {
    /* Load DLL into memory */
    HINSTANCE ProcDLL_ESS;

    #ifdef _WIN64
    ProcDLL_ESS = LoadLibrary(TEXT("ess_c_64.dll"));
    #else
    ProcDLL_ESS = LoadLibrary(TEXT("ess_c_32.dll"));
    #endif

    /* Declare pointers on dll functions */
    init dll_init;
    serial dll_serial;
    close dll_close;

            dll_init = (init)GetProcAddress(ProcDLL_ESS, "ess_initialization");
    dll_serial = (serial)GetProcAddress(ProcDLL_ESS, "ess_get_serial");
    dll_close = (close)GetProcAddress(ProcDLL_ESS, "ess_close");

    unsigned long long essHandle = 0;
    unsigned short Serial = 0;
    unsigned short Version = 0;
    unsigned char position = 0;

                    if (ProcDLL_ESS != NULL) {
    std::cout << "ESS dll loaded" << std::endl;

    /* Initialize device */
    if (dll_init != NULL) {
    /* Initialize the first SWITCHBOARD in Windows enumeration list */
    essHandle = dll_init(0);
    std::cout << "ESS session initialized" << std::endl;
    }

    /* Read device serial number */
    if (dll_serial != NULL) {
    /*Get the serial number of the SWITCHBOARD*/
    dll_serial(essHandle, &Serial, &Version);
    std::cout << "SWITCH BOARD SN: " << Serial << std::endl;
    }

              return EXIT_SUCCESS;

    }



           
    • Edited by varun_bwazz Monday, November 11, 2019 7:22 AM
    Monday, November 11, 2019 7:09 AM

Answers

  • Hello varun_bwazz,

    1. Change the API names as follows :

    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern Int64 ess_initialization(int i);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int ess_get_serial(UInt64 ull, ref ushort pushort1, ref ushort pushort2);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int ess_close(UInt64 ull);

    2. Sorry that I didn't realize that the names in the calls to GetProcAddress() in the C++ code from the OP were different from the typedef declarations.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    • Marked as answer by varun_bwazz Saturday, November 16, 2019 5:42 AM
    Monday, November 11, 2019 10:09 AM
  • Thank you RLWA32

    I am no more getting 'Entry point not found error'.I have written the c++ code which i had mentioned above in c#. The code has some run time error which I could not recognize. Please correct me if you find any. The code is given below. The program is built successfully but not running.

    /*PROGRAM.cs*/

    using System;

    using System.Runtime.InteropServices;
    using System.Threading;

    namespace nmspace
    {
        class Program
        {
                           [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_initialization(int i);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_serial(UInt64 ull, ref ushort serial, ref ushort version);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_close(UInt64 ull);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_two_switch(UInt64 handle, byte two_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte status, ref byte origin);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_rot_switch(UInt64 handle, byte rot_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte err_code, ref byte processing, ref byte position);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_set_all_rot_switch(UInt64 handle, byte rot_switch, byte position, byte direction);

           private static void Test()
            {
                byte two_switch = 0;
                byte rot_switch = 0;
                UInt64 essHandle=0;
                ushort serial = 0;
                ushort version = 0;
                byte position = 0;
                byte Presence = 0;
                byte type = 0;
                byte model = 0;
                byte soft_vers = 0;
                byte status = 0;
                byte origin = 0;
                byte err_code = 0;
                byte processing = 0;
                byte direction = 0;

                ess_initialization(0);/*Initialization*/
                Console.Write("ESS Initialized");

                Int64 iValSerial = ess_get_serial(essHandle, ref serial, ref version);/*get serial*/
                Console.Write("SWITCH BOARD SN:" +(int) serial);



                ess_get_data_two_switch(essHandle, two_switch, ref Presence, ref type, ref model, ref soft_vers, ref status, ref origin);
                if ((Presence == 1) && (type == 1))
                {                                               // If 2-SWITCH detected
                    Console.Write("2-SWITCH detected.");
                    Console.Write("Model (1 if 2-SWITCH):" + (int)model); // Display model
                    Console.Write("Software version: " + (int)soft_vers);// Display software version
                    if (status == 1)
                    {
                        // Display 2-SWITCH status 
                        Console.Write("Switch is ON.");
                    }
                    else
                    {
                        Console.Write("Switch is OFF.");
                    }
                }
                else
                {
                    Console.Write("No 2-SWITCH found on 1st position.");
                }


                ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);

                if ((Presence == 1) && (type == 0))
                {                                               // If SWITCH detected
                    Console.Write("ROT-SWITCH detected.");
                    Console.Write("Model (1: M-SWITCH; 3: L-SWITCH): " + model);// Display model
                    Console.Write("Software version: " + (int)soft_vers); // Display software version
                    Console.Write("Switch position: " + (int)position);   // Display ROT-SWITCH position

                    if (position == 0)
                    {
                        ess_set_all_rot_switch(essHandle, rot_switch, 0, 1);
                    }
                    else
                    {
                       ess_set_all_rot_switch(essHandle, rot_switch, 0, 0);
                        Console.Write("ROT-SWITCH position changed!");
                    }
                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing != 1);
                    Thread.Sleep(100);

                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing == 1);
                    Thread.Sleep(100);

                    // Read new position after change
                    ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                    Console.Write("New Switch position: " + (int)position);
                }  // Display ROT-SWITCH position
                else
                {
                    Console.Write("No ROT-SWITCH found on position 'A'.");
                }
                ess_close(0);
                Console.Write("ESS session closed");
            }


            public static void Main(String[] args)
            {
                Test();
            }
        }
    }


    • Edited by varun_bwazz Friday, November 15, 2019 5:42 AM
    • Marked as answer by varun_bwazz Friday, November 15, 2019 9:49 AM
    Friday, November 15, 2019 5:39 AM

All replies

  • Hello varun_bwazz,

    1. In C#, to use an exported API from an unmanaged DLL, you would use the DllImport Attribute to define a static extern method, e.g. :

    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern Int64 init(int i);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int serial(UInt64 ull, ref ushort pushort1, ref ushort pushort2);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int close(UInt64 ull);

    Note that you need to add "using System.Runtime.InteropServices;" to your C# source file.

    2. You would then call these externally defined APIs in your code as per normal :

    private static void DoTest()
    {
        Int64 iValInit = init(0);
    
        ushort ushort1 = 0;
        ushort ushort2 = 0;
        int iValSerial = serial(0, ref ushort1, ref ushort2);
    
        int iValClose = close(0);
    }
    3. There is no need to declare function pointers in C#. The handling of the DLL loading and function address linking are performed automatically by the .NET Marshaler.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/



    Monday, November 11, 2019 9:20 AM
  • Thank you. 

    I tried the above concept where i got an error saying "System.EntryPointNotFoundException' in tryDLL.exe". What to do with that? . I have passed an Entry point method in the dll import. Still m getting the same error. 

    Monday, November 11, 2019 9:43 AM
  • Hello varun_bwazz,

    1. Change the API names as follows :

    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern Int64 ess_initialization(int i);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int ess_get_serial(UInt64 ull, ref ushort pushort1, ref ushort pushort2);
    
    [DllImport("<path to DLL>", CallingConvention = CallingConvention.StdCall)]
    private static extern int ess_close(UInt64 ull);

    2. Sorry that I didn't realize that the names in the calls to GetProcAddress() in the C++ code from the OP were different from the typedef declarations.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    • Marked as answer by varun_bwazz Saturday, November 16, 2019 5:42 AM
    Monday, November 11, 2019 10:09 AM
  • The typedefs for the exported functions are incorrect.  Their signatures do not match those of the exported functions.

    For example, ess_inintialization takes an unsigned short parameter but the typedef uses an int.  Both ess_close and ess_get_serial return an unsigned char but their typedefs return int.

    Monday, November 11, 2019 12:10 PM
  • Suggest a way to implement the below code in c#. I am stuck with function pointers and explicit calling of function pointers using getProcAdress()

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    //#include "ess_c.h"

    /* Define functions prototype */
    typedef unsigned long long(__stdcall *init)(int);
    typedef int(__stdcall *serial)(unsigned long long, unsigned short *, unsigned short *);
    typedef int(__stdcall *close)(unsigned long long);
    typedef int(__stdcall *read2SWITCH)(unsigned long long handle, unsigned char two_switch, unsigned char * presence,
    unsigned char * type, unsigned char * model, unsigned char * soft_vers, unsigned char * status, unsigned char * origin);
    typedef int(__stdcall *readROTSWITCH)(unsigned long long handle, unsigned char rot_switch, unsigned char * presence,
    unsigned char * type, unsigned char * model, unsigned char * soft_vers, unsigned char * err_code,
    unsigned char * processing, unsigned char * position);
    typedef int(__stdcall *setROTSWITCH)(unsigned long long handle, unsigned char rot_switch, unsigned char position, unsigned char direction);

    int main(int argc, char *argv[])
    {
    /* Load DLL into memory */
    HINSTANCE ProcDLL_ESS;

    #ifdef _WIN64
    ProcDLL_ESS = LoadLibrary(TEXT("ess_c_64.dll"));
    #else
    ProcDLL_ESS = LoadLibrary(TEXT("ess_c_32.dll"));
    #endif

    /* Declare pointers on dll functions */
    init dll_init;
    serial dll_serial;
    close dll_close;
    read2SWITCH dll_read2SWITCH;
    readROTSWITCH dll_readROTSWITCH;
    setROTSWITCH dll_setROTSWITCH;

    /* Link dll pointers with functions prototype */
    dll_init = (init)GetProcAddress(ProcDLL_ESS, "ess_initialization");
    dll_serial = (serial)GetProcAddress(ProcDLL_ESS, "ess_get_serial");
    dll_close = (close)GetProcAddress(ProcDLL_ESS, "ess_close");
    dll_read2SWITCH = (read2SWITCH)GetProcAddress(ProcDLL_ESS, "ess_get_data_two_switch");
    dll_readROTSWITCH = (readROTSWITCH)GetProcAddress(ProcDLL_ESS, "ess_get_data_rot_switch");
    dll_setROTSWITCH = (setROTSWITCH)GetProcAddress(ProcDLL_ESS, "ess_set_rot_switch");

    /* Define variables used for ESS */
    unsigned long long essHandle = 0;
    unsigned short Serial = 0;
    unsigned short Version = 0;
    unsigned char position = 0;
    unsigned char two_switch = 0; // 2-SWITCH position (0 is the 1st on the SWITCHBOARD)
    unsigned char rot_switch = 0; // ROT-SWITCH position (0 is the 1st, position 'A')

    /* SWITCH variables definition used by the shared library */
    unsigned char Presence;
    unsigned char Type;
    unsigned char Model;
    unsigned char Software_Version;
    unsigned char Status;
    unsigned char Origin;
    unsigned char Err_code;
    unsigned char Processing;
    unsigned char Position;

    unsigned int localCount = 0;

    if (ProcDLL_ESS != NULL) { // If dll loaded
    std::cout << "ESS dll loaded" << std::endl;

    /* Initialize device */
    if (dll_init != NULL) { // Check if function was properly linked to the dll file
    /* Initialize the first SWITCHBOARD in Windows enumeration list */
    essHandle = dll_init(0);
    std::cout << "ESS session initialized" << std::endl;
    }

    /* Read device serial number */
    if (dll_serial != NULL) {
    /*Get the serial number of the SWITCHBOARD*/
    dll_serial(essHandle, &Serial, &Version);
    std::cout << "SWITCH BOARD SN: " << Serial << std::endl;
    }

    /* Get status of the 2-SWITCH (N°1 on the board) */
    if (dll_read2SWITCH != NULL){
    dll_read2SWITCH(essHandle, two_switch, &Presence, &Type, &Model, &Software_Version, &Status, &Origin);
    if ((Presence == 1) && (Type == 1)){ // If 2-SWITCH detected
    std::cout << std::endl << "2-SWITCH detected." << std::endl;
    std::cout << "Model (1 if 2-SWITCH): " << int(Model) << std::endl; // Display model
    std::cout << "Software version: " << int(Software_Version) << std::endl; // Display software version
    if (Status == 1){ // Display 2-SWITCH status 
    std::cout << "Switch is ON." << std::endl;
    }
    else{ std::cout << "Switch is OFF." << std::endl; }
    }
    else{ std::cout << "No 2-SWITCH found on 1st position." << std::endl; }
    }

    /* Get status of the ROT-SWITCH (N°A on the board) */
    if (dll_readROTSWITCH != NULL){
    dll_readROTSWITCH(essHandle, rot_switch, &Presence, &Type, &Model, &Software_Version, &Err_code, &Processing, &Position);
    if ((Presence == 1) && (Type == 0)){ // If SWITCH detected
    std::cout << std::endl << "ROT-SWITCH detected." << std::endl;
    std::cout << "Model (1: M-SWITCH; 3: L-SWITCH): " << int(Model) << std::endl; // Display model
    std::cout << "Software version: " << int(Software_Version) << std::endl; // Display software version
    std::cout << "Switch << int(Position) << std::endl; // Display ROT-SWITCH position

    /* Change ROT-SWITCH position */
    if (Position == 0){ // SWITCH changes from position 1 to 0 or from 0 to 1
    dll_setROTSWITCH(essHandle, rot_switch, 1, 0);
    }
    else{
    dll_setROTSWITCH(essHandle, rot_switch, 0, 0);
    }
    std::cout << "ROT-SWITCH position changed!" << std::endl;

    /* Wait for processing flag to be active */
    do {
    dll_readROTSWITCH(essHandle, rot_switch, &Presence, &Type, &Model, &Software_Version, &Err_code, &Processing, &Position);
    Sleep(100);
    } while (Processing != 1);
    Sleep(100);

    /* Wait for processing flag to be down */
    do{
    dll_readROTSWITCH(essHandle, rot_switch, &Presence, &Type, &Model, &Software_Version, &Err_code, &Processing, &Position);
    Sleep(100);
    } while (Processing == 1);
    Sleep(100);

    // Read new position after change
    dll_readROTSWITCH(essHandle, rot_switch, &Presence, &Type, &Model, &Software_Version, &Err_code, &Processing, &Position);
    std::cout << "New Switch << int(Position) << std::endl; // Display ROT-SWITCH position
    }
    else{ std::cout << "No ROT-SWITCH found on position 'A'." << std::endl; }
    }

    /* Close ESS session */
    if (dll_close != NULL) {
    dll_close(essHandle);
    std::cout << std::endl << "ESS session closed" << std::endl;
    }
    }

    /* Release the DLL */
    FreeLibrary(ProcDLL_ESS);
    std::cout << "ESS dll unloaded" << std::endl;

    /* Exit application */
    system("PAUSE");

    return EXIT_SUCCESS;
    }

    Tuesday, November 12, 2019 6:02 AM
  • Hello varun_bwazz,

    1. I suggest that you download the Dependency Walker tool and use it to make sure that the DLL that you specified in the DllImport Attribute actually does export the correct required APIs.

    2. There are 2 versions of Dependency Walker : one for 64-bits and one for 32-bits.

    3. If in doubt, specify the full path to the DLL in the DllImport Attribute.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, November 12, 2019 8:34 AM
  • Hi varun,

    Thank you for posting here.

    I noticed your error : System.EntryPointNotFoundException in tryDLL.exe.

    Do you compile your C++ application into an exe file instead of a dll file?

    If you want to use a C++ application in a C# application, you'd better compile it into a dynamic link library and then use it in the way provided by Lim Bio Liong.

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 12, 2019 8:55 AM
  • hi Timon Yang

    I have a c++ application which is using a already  compiled  external dll in the run time using GetProcAddress().  "I  only have the .h file of dll"

    In the same way I want to use the external dll in c#. 




    • Edited by varun_bwazz Tuesday, November 12, 2019 9:21 AM
    Tuesday, November 12, 2019 9:19 AM
  • Hello varun_bwazz,

    1. The System.EntryPointNotFoundException description you showed in an earlier post indicated that you are pointing at tryDLL.exe as indicated by Timon Yang.

    2. Make sure that the DllImport Attributes point to either ess_c_64.dll or ess_c_32.dll (select according to the platform your C# application is running on).

    3. If possible, show us your code especially how you declared the DllImports.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, November 12, 2019 9:29 AM
  • Show us how you are exporting the functions from the dll.

    Tuesday, November 12, 2019 9:35 AM
  • / This is how used DllImport/
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            private static extern Int64 ess_initialization(int i);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            private static extern Int64 ess_get_serial(UInt64 ull, ref ushort serial, ref ushort version);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            private static extern Int64 ess_close(UInt64 ull);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall,CharSet = CharSet.Unicode)]
            private static extern Int64 ess_get_data_two_switch(UInt64 ull, byte two_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte status, ref byte origin);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            private static extern Int64 ess_get_data_rot_switch(UInt64 ull, byte rot_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte err_code, ref byte processing, ref byte position);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            private static extern Int64 ess_set_all_rot_switch(UInt64 ull, byte position, byte direction);


            private static void Test()
            {

                Int64 iValInit = ess_initialization(0);
                ushort serial = 0;
                ushort version = 0;


                Int64 iValSerial = ess_get_serial(0, ref serial, ref version);

                Int64 iValClose = ess_close(0);


            }


            public static void Main(String[] args)
            {
               
                    }

        }
     }
    Tuesday, November 12, 2019 9:44 AM
  • Hello varun_bwazz,

    1. The declarations look OK.

    2. I suggest that you use the Dependency Walker to examine ess_c_64.dll to make sure that the APIs, e.g. ess_initialization(), ess_get_serial(), etc are actually exported with the exact same names (i.e. with no decorations like @ or _).

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, November 12, 2019 10:09 AM
  • Thanks Lim Bio Liong

    I tried dependency walker and dot peek software to read dll . but the dll file is not supporting.

    What would be the reason?. Is it because its WIN32 file?

    Tuesday, November 12, 2019 10:19 AM
  • From a Visual Studio Command Prompt run Dumpbin /EXPORTS on the dll
    Tuesday, November 12, 2019 10:21 AM
  • Hello varun_bwazz,

    Please use the DUMPBIN.exe utility as suggested by RLWA32.

    Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, November 12, 2019 2:12 PM

  • I got the methods using dumpbin

     Section contains the following exports for ess_c.dll

       

        ordinal hint RVA      name

             15    0 00061DF0 __CPPdebugHook
              2    1 000024E0 ess_close
              5    2 00002740 ess_detect
             14    3 00003600 ess_get_check_led
             11    4 00003310 ess_get_data_rot_switch
             12    5 000033E0 ess_get_data_two_switch
              6    6 00002C80 ess_get_serial
              1    7 00002320 ess_initialization
              3    8 00002580 ess_read
              8    9 00002E80 ess_set_all_rot_switch
             10    A 000031B0 ess_set_all_two_switch
             13    B 000034A0 ess_set_check_led
              7    C 00002CE0 ess_set_rot_switch
              9    D 00003050 ess_set_two_switch
              4    E 00002610 ess_write

     


    • Edited by varun_bwazz Wednesday, November 13, 2019 8:49 AM
    Wednesday, November 13, 2019 5:47 AM
  •  Section contains the following exports for ess_c.dll

    So what is the actual name of the dlls in use?

    ess_c.dll is not the same name that you have used in previous posts which mentioned either ess_c_32.dll or ess_c_64.dll.

    Do either of those have the proper exports?


    Wednesday, November 13, 2019 9:19 AM
  • I run the dumpbin export on the 'ess_c_64.dll' which promped the above mentioned export methods.

    I dont have the cpp file of 'ess_c_64.dll'. I have only the .h file

    /prog.h/

    #ifndef ess_cH
    #define ess_cH

    unsigned long long __stdcall ess_initialization(unsigned short serial);


    unsigned char __stdcall ess_close(unsigned long long handle);


    unsigned char __stdcall ess_get_serial(unsigned long long handle,
             unsigned short * serial,
                                           unsigned short * version);
       

    unsigned char __stdcall ess_set_rot_switch(unsigned long long handle,
            unsigned char rot_switch,
                                           unsigned char position,
                                           unsigned char direction);
       

    unsigned char __stdcall ess_set_all_rot_switch(unsigned long long handle,
                                           unsigned char position,
                                           unsigned char direction);


    unsigned char __stdcall ess_set_two_switch(unsigned long long handle,
          unsigned char two_switch,
                                           unsigned char position);


    unsigned char __stdcall ess_set_all_two_switch(unsigned long long handle,
                                           unsigned char position);
       

    unsigned char __stdcall ess_get_data_rot_switch(unsigned long long handle,
    unsigned char rot_switch,
        unsigned char * presence,
                                            unsigned char * type,
                                            unsigned char * model,
                                            unsigned char * soft_vers,
                                            unsigned char * err_code,
                                            unsigned char * processing,
                                            unsigned char * position);


    unsigned char __stdcall ess_get_data_two_switch(unsigned long long handle,
            unsigned char two_switch,
                unsigned char * presence,
                                            unsigned char * type,
                                            unsigned char * model,
                                            unsigned char * soft_vers,
                                            unsigned char * status,
                                            unsigned char * origin);


    unsigned char __stdcall ess_detect(unsigned short table[256]);

    // return values

    #define ESS_OK     0
    #define ESS_ERR_USB_CLOSED     1
    #define ESS_ERR_COMMAND     2
    #define ESS_ERR_NO_SWITCH     3
    #define ESS_ERR_WRONG_SWITCH 4


    #endif

    Wednesday, November 13, 2019 9:50 AM
  • Based on the information provided up to this point I can see no reason why a System.EntryPointNotFoundException would be thrown.

    So I get the feeling that we are not seeing the actual code that is being used.

    Wednesday, November 13, 2019 11:43 AM
  • Thank you RLWA32

    I am no more getting 'Entry point not found error'.I have written the c++ code which i had mentioned above in c#. The code has some run time error which I could not recognize. Please correct me if you find any. The code is given below. The program is built successfully but not running.

    /*PROGRAM.cs*/

    using System;

    using System.Runtime.InteropServices;
    using System.Threading;

    namespace nmspace
    {
        class Program
        {
                           [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_initialization(int i);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_serial(UInt64 ull, ref ushort serial, ref ushort version);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_close(UInt64 ull);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_two_switch(UInt64 handle, byte two_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte status, ref byte origin);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_rot_switch(UInt64 handle, byte rot_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte err_code, ref byte processing, ref byte position);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_set_all_rot_switch(UInt64 handle, byte rot_switch, byte position, byte direction);

           private static void Test()
            {
                byte two_switch = 0;
                byte rot_switch = 0;
                UInt64 essHandle=0;
                ushort serial = 0;
                ushort version = 0;
                byte position = 0;
                byte Presence = 0;
                byte type = 0;
                byte model = 0;
                byte soft_vers = 0;
                byte status = 0;
                byte origin = 0;
                byte err_code = 0;
                byte processing = 0;
                byte direction = 0;

                ess_initialization(0);/*Initialization*/
                Console.Write("ESS Initialized");

                Int64 iValSerial = ess_get_serial(essHandle, ref serial, ref version);/*get serial*/
                Console.Write("SWITCH BOARD SN:" +(int) serial);



                ess_get_data_two_switch(essHandle, two_switch, ref Presence, ref type, ref model, ref soft_vers, ref status, ref origin);
                if ((Presence == 1) && (type == 1))
                {                                               // If 2-SWITCH detected
                    Console.Write("2-SWITCH detected.");
                    Console.Write("Model (1 if 2-SWITCH):" + (int)model); // Display model
                    Console.Write("Software version: " + (int)soft_vers);// Display software version
                    if (status == 1)
                    {
                        // Display 2-SWITCH status 
                        Console.Write("Switch is ON.");
                    }
                    else
                    {
                        Console.Write("Switch is OFF.");
                    }
                }
                else
                {
                    Console.Write("No 2-SWITCH found on 1st position.");
                }


                ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);

                if ((Presence == 1) && (type == 0))
                {                                               // If SWITCH detected
                    Console.Write("ROT-SWITCH detected.");
                    Console.Write("Model (1: M-SWITCH; 3: L-SWITCH): " + model);// Display model
                    Console.Write("Software version: " + (int)soft_vers); // Display software version
                    Console.Write("Switch position: " + (int)position);   // Display ROT-SWITCH position

                    if (position == 0)
                    {
                        ess_set_all_rot_switch(essHandle, rot_switch, 0, 1);
                    }
                    else
                    {
                       ess_set_all_rot_switch(essHandle, rot_switch, 0, 0);
                        Console.Write("ROT-SWITCH position changed!");
                    }
                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing != 1);
                    Thread.Sleep(100);

                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing == 1);
                    Thread.Sleep(100);

                    // Read new position after change
                    ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                    Console.Write("New Switch position: " + (int)position);
                }  // Display ROT-SWITCH position
                else
                {
                    Console.Write("No ROT-SWITCH found on position 'A'.");
                }
                ess_close(0);
                Console.Write("ESS session closed");
            }


            public static void Main(String[] args)
            {
                Test();
            }
        }
    }


    • Edited by varun_bwazz Friday, November 15, 2019 5:42 AM
    • Marked as answer by varun_bwazz Friday, November 15, 2019 9:49 AM
    Friday, November 15, 2019 5:39 AM
  • Thank you RLWA32

    I am no more getting 'Entry point not found error'.I have written the c++ code which i had mentioned above in c#. The code has some run time error which I could not recognize. Please correct me if you find any. The code is given below. The program is built successfully but not running.

    /*PROGRAM.cs*/

    using System;

    using System.Runtime.InteropServices;
    using System.Threading;

    namespace nmspace
    {
        class Program
        {
                           [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_initialization(int i);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_serial(UInt64 ull, ref ushort serial, ref ushort version);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_close(UInt64 ull);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_two_switch(UInt64 handle, byte two_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte status, ref byte origin);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_get_data_rot_switch(UInt64 handle, byte rot_switch, ref byte presence, ref byte type, ref byte model, ref byte soft_vers, ref byte err_code, ref byte processing, ref byte position);
            [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
            private static extern Int64 ess_set_all_rot_switch(UInt64 handle, byte rot_switch, byte position, byte direction);

           private static void Test()
            {
                byte two_switch = 0;
                byte rot_switch = 0;
                UInt64 essHandle=0;
                ushort serial = 0;
                ushort version = 0;
                byte position = 0;
                byte Presence = 0;
                byte type = 0;
                byte model = 0;
                byte soft_vers = 0;
                byte status = 0;
                byte origin = 0;
                byte err_code = 0;
                byte processing = 0;
                byte direction = 0;

                ess_initialization(0);/*Initialization*/
                Console.Write("ESS Initialized");

                Int64 iValSerial = ess_get_serial(essHandle, ref serial, ref version);/*get serial*/
                Console.Write("SWITCH BOARD SN:" +(int) serial);



                ess_get_data_two_switch(essHandle, two_switch, ref Presence, ref type, ref model, ref soft_vers, ref status, ref origin);
                if ((Presence == 1) && (type == 1))
                {                                               // If 2-SWITCH detected
                    Console.Write("2-SWITCH detected.");
                    Console.Write("Model (1 if 2-SWITCH):" + (int)model); // Display model
                    Console.Write("Software version: " + (int)soft_vers);// Display software version
                    if (status == 1)
                    {
                        // Display 2-SWITCH status 
                        Console.Write("Switch is ON.");
                    }
                    else
                    {
                        Console.Write("Switch is OFF.");
                    }
                }
                else
                {
                    Console.Write("No 2-SWITCH found on 1st position.");
                }


                ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);

                if ((Presence == 1) && (type == 0))
                {                                               // If SWITCH detected
                    Console.Write("ROT-SWITCH detected.");
                    Console.Write("Model (1: M-SWITCH; 3: L-SWITCH): " + model);// Display model
                    Console.Write("Software version: " + (int)soft_vers); // Display software version
                    Console.Write("Switch position: " + (int)position);   // Display ROT-SWITCH position

                    if (position == 0)
                    {
                        ess_set_all_rot_switch(essHandle, rot_switch, 0, 1);
                    }
                    else
                    {
                       ess_set_all_rot_switch(essHandle, rot_switch, 0, 0);
                        Console.Write("ROT-SWITCH position changed!");
                    }
                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing != 1);
                    Thread.Sleep(100);

                    do
                    {
                        ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                        Thread.Sleep(100);
                    }
                    while (processing == 1);
                    Thread.Sleep(100);

                    // Read new position after change
                    ess_get_data_rot_switch(essHandle, rot_switch, ref Presence, ref type, ref model, ref soft_vers, ref err_code, ref processing, ref position);
                    Console.Write("New Switch position: " + (int)position);
                }  // Display ROT-SWITCH position
                else
                {
                    Console.Write("No ROT-SWITCH found on position 'A'.");
                }
                ess_close(0);
                Console.Write("ESS session closed");
            }


            public static void Main(String[] args)
            {
                Test();
            }
        }
    }


    First, you should carefully review all of your DllImports to ensure that they EXACTLY match the function declarations in the dll header file with respect to the types for return values and function parameters.  There are numerous discrepancies, the most severe one being that the DllImport for the ess_set_all_rot_switch function is incorrect because it includes a parameter that  is not present in the C header.

    unsigned char __stdcall ess_set_all_rot_switch(unsigned long long handle,
                                           unsigned char position,
                                           unsigned char direction);

    [DllImport("C:\\Users\\JivaSci\\Desktop\\fluigent\\bin\\SDK\\ESS\\C++\\Cpp_Windows\\ess_c_64.dll", CallingConvention = CallingConvention.StdCall)]
    private static extern Int64 ess_set_all_rot_switch(UInt64 handle, byte rot_switch, byte position, byte direction);

    It is not possible for us to test your code.

    However, you should provide details when you say "The code has some run time error which I could not recognize."

    Perhaps the runtime error is due to the incorrect DllImport statements.

    Friday, November 15, 2019 11:02 AM