need help importing the native DLL??

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Suzan YILDIRIM
    New Member
    • Jan 2010
    • 9

    need help importing the native DLL??

    Hi,

    i have a native or an unmanaged DLL that i will use this DLL to conrol an external device and i have tried to call it into c# but i have trouble with non-Blittable types...i have tried marshal these types but i'm not sure whether i achieved it..??

    thanks in advance

    Suzan
  • Suzan YILDIRIM
    New Member
    • Jan 2010
    • 9

    #2
    i have a native or an unmanaged DLL that i will use this DLL to conrol an external device and i have tried to call it into c# but i have trouble with non-Blittable types...i have tried marshal these types but i'm not sure whether i achieved it..??
    for example;

    Code:
    typedef struct
    {
    	unsigned char TagType;
    	unsigned char AntNum;
    	unsigned char Ids[12];
    }TagIds;
    
    /***************C# Convert**********************/
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            public struct TagIds
            {
                public byte TagType;
                public byte AntNum;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
                string Ids;
            }
    
    /****************C# Convert*******************/
    is there any problem with this conversion??
    Last edited by tlhintoq; Jan 31 '10, 04:30 PM. Reason: [CODE] ...Your code goes between code tags [/CODE]

    Comment

    • dennisoleksyuk
      New Member
      • Jan 2010
      • 17

      #3
      Can you post C header for the function that you are trying to call?

      Comment

      • Suzan YILDIRIM
        New Member
        • Jan 2010
        • 9

        #4
        Code:
        __declspec(dllexport) __stdcall short DrfIsoMultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr);
        and the function is used like this

        Code:
             if(DrfIsoMultiTagIdentify(ComHandle,&Cnt,TagData,0Xff)==0)
             {
                  for(i = 0; i < Cnt; i++)
                      OutputDate(TagData[i]);
             }
        Last edited by tlhintoq; Jan 31 '10, 04:30 PM. Reason: [CODE] ...Your code goes between code tags [/CODE]

        Comment

        • tlhintoq
          Recognized Expert Specialist
          • Mar 2008
          • 3532

          #5
          TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out.

          Comment

          • Suzan YILDIRIM
            New Member
            • Jan 2010
            • 9

            #6
            TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out.
            sorry i didn't know it.. i do

            Comment

            • Suzan YILDIRIM
              New Member
              • Jan 2010
              • 9

              #7
              and the C header file for the functions that i am trying to call is

              Code:
              typedef struct
              {
              	unsigned char TagType;
              	unsigned char AntNum;
              	unsigned char Ids[12];
              }TagIds;
              typedef short apiStatus;
              
              apiStatus __declspec(dllexport) __stdcall DrfCommOpen (HANDLE * hCom, char *com_port);
              apiStatus __declspec(dllexport) __stdcall DrfCommClose (HANDLE hCom);
              apiStatus __declspec(dllexport) __stdcall DrfSetParameter (HANDLE hCom, unsigned int iRomAddr, unsigned char value,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGetParameter (HANDLE hCom , unsigned int iRomAddr, unsigned char *value,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetMultiParameter(HANDLE hCom , unsigned int iRomAddr, unsigned char ParaCount,unsigned char * Parameters, unsigned char ReaderAddr = 0xff); 
              apiStatus __declspec(dllexport) __stdcall DrfGetMultiParameter(HANDLE hCom, unsigned int iRomAddr, unsigned char ParaCount,unsigned char *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetBaudRate(HANDLE hCom, USHORT BaudRate, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfReset (HANDLE hCom, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetWorkAntenna (HANDLE hCom, unsigned char Antenna, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetRf(HANDLE hCom,unsigned char power,unsigned char freq_type,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGetRf(HANDLE hCom,unsigned char * power,unsigned char  *freq_type,unsigned char ReaderAddr = 0xff) ;
              apiStatus __declspec(dllexport) __stdcall DrfSetAntennaCycle (HANDLE hCom, unsigned char Cycle, unsigned char ReaderAddr = 0xff) ;
              apiStatus __declspec(dllexport) __stdcall DrfAntennaQuery( HANDLE hCom, unsigned char* Receive, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetFrequency (HANDLE hCom, unsigned char Channel, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGetFrequency (HANDLE hCom, unsigned char *Channel, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfSetPower(HANDLE hCom, USHORT Mode, UCHAR PowerLevel, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGetPower(HANDLE hCom, UCHAR *PowerLevel, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGetFirmwareVersion (HANDLE hCom, unsigned char *major,unsigned char *minor, unsigned char ReaderAddr = 0xff);
              
              apiStatus __declspec(dllexport) __stdcall DrfIsoReadWithID(HANDLE hCom, unsigned char* TagID,unsigned char iRomAddr,unsigned char *AntNum,unsigned char* value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoWriteWithID(HANDLE hCom, unsigned char* TagID,unsigned char iRomAddr,unsigned char value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoMultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoMultiTagRead(HANDLE hCom,  unsigned char iRomAddr,unsigned int * Count,TagIds *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoWriteTag(HANDLE hCom ,unsigned char iRomAddr,unsigned char value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoBlockWrite(HANDLE hCom, unsigned char iRomAddr,unsigned char length,unsigned char* value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoLockTag(HANDLE hCom ,unsigned char iRomAddr, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfIsoQueryLock(HANDLE hCom, unsigned char iRomAddr,unsigned char *status, unsigned char ReaderAddr = 0xff);
              
              apiStatus __declspec(dllexport) __stdcall DrfGen2SingleRead(HANDLE hCom, unsigned char MemBank,unsigned char WordCount,unsigned char *AntNum,unsigned char* value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGen2MultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGen2WriteTag(HANDLE hCom ,unsigned char iRomAddr,unsigned int value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGen2LockTag(HANDLE hCom,unsigned char MemBank = 1, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGen2KillTag(HANDLE hCom ,unsigned char PassWord, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfGen2InitTag(HANDLE hCom, unsigned char BitCount = 96, unsigned char ReaderAddr = 0xff);
              
              apiStatus __declspec(dllexport) __stdcall DrfClass1SingleIdentify(HANDLE hCom,unsigned char * AntNum, unsigned char *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfClass1MultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall DrfClass1Program(HANDLE hCom, unsigned char * Values,unsigned char ReaderAddr = 0xff);
              
              apiStatus __declspec(dllexport) __stdcall GetTagData(HANDLE hCom,int Count,TagIds *value, unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall ClearIDBuffer(HANDLE hCom,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall QueryIDCount(HANDLE hCom,unsigned char* Count,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall GetIDACK(HANDLE hCom,unsigned char ReaderAddr = 0xff);
              apiStatus __declspec(dllexport) __stdcall GetId(HANDLE hCom,unsigned char *value,unsigned char ReaderAddr = 0xff);
              
              ////////////////////////////////////////////////////////////////////////////////////////////////
              apiStatus __declspec(dllexport) __stdcall GetTwoID(HANDLE hCom,unsigned char *Count,unsigned char *value,unsigned char ReaderAddr = 0xff);

              Comment

              • dennisoleksyuk
                New Member
                • Jan 2010
                • 17

                #8
                I created library with the same function exposed as your RFID driver. Then I called that function from .NET.

                Header that I created:
                Code:
                typedef struct
                {
                	unsigned char TagType;
                	unsigned char AntNum;
                	unsigned char Ids[12];
                }TagIds;
                
                typedef unsigned long HANDLE;
                typedef short apiStatus;
                
                apiStatus __declspec(dllexport) __stdcall DrfIsoMultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr = 0xff);
                Implementation for the header
                Code:
                #include "function.h"
                
                apiStatus __declspec(dllexport) __stdcall DrfIsoMultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr){
                	*Count = 1;
                
                	value->AntNum = 2;
                	value->TagType = 3;
                	for(int i=0; i<12;i++){
                		value->Ids[i] = i+4;
                	}
                
                	return 0;
                }
                Here is .NET code that calls that function
                Code:
                using System;
                using System.Collections.Generic;
                using System.Runtime.InteropServices;
                using System.Text;
                
                namespace RunTestDriver
                {
                    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
                        public struct TagIds
                        {
                            public byte TagType;
                            public byte AntNum;
                            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
                            public byte[] Ids;
                        }
                    
                    class Program
                    {
                        //short __declspec(dllexport) __stdcall DrfIsoMultiTagIdentify(HANDLE hCom, unsigned int * Count,TagIds *value, unsigned char ReaderAddr){
                
                        [DllImport("TestDriver.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "?DrfIsoMultiTagIdentify@@YGFKPAIPAUTagIds@@E@Z")]
                        static extern short DrfIsoMultiTagIdentify(uint hCom, ref int Count, ref TagIds value, byte ReaderAddr);
                
                        static void Main(string[] args)
                        {
                            Console.WriteLine("Press enter to start");
                            Console.ReadLine();
                
                            TagIds tag = new TagIds();
                            tag.Ids = new byte[12];
                            int count = 0;
                            Console.WriteLine(DrfIsoMultiTagIdentify(1,ref count,ref tag,1));
                            Console.WriteLine(count);
                            Console.WriteLine(tag.AntNum);
                            Console.WriteLine(tag.TagType);
                            for (int i = 0; i < 12; i++) {
                                Console.WriteLine(tag.Ids[i]);
                            }
                
                
                            Console.WriteLine("Press enter to finish");
                            Console.ReadLine();
                        }
                    }
                }
                Example code shows numbers from 0 to 15. It indicates that all structures where passed to the C++ code and back successfully.

                Let us know if this solution works for you.

                Comment

                • Suzan YILDIRIM
                  New Member
                  • Jan 2010
                  • 9

                  #9
                  btw i'm not the writer of this DLL..

                  Code:
                  [DllImport("TestDriver.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "?DrfIsoMultiTagIdentify@@YGFKPAIPAUTagIds@@E@Z")]
                  the name of the dll is DrfApiV10 so should i use this name instead of TestDriver.dll and i don't understand Implementation for the header
                  that you have created..can you clarify it for me please??

                  Comment

                  • dennisoleksyuk
                    New Member
                    • Jan 2010
                    • 17

                    #10
                    I created that DLL because I don't have real dll and equipment that it uses. It just have the same convention as your DLL. You don't need to create it. I needed to check my C# code somehow.

                    Yes you need to put DrfApiV10.dll in place of TestDriver.dll in my example.

                    Whitin my C++ implementation I'm returning 0 as a result of function, assigning 1 to Count, assigning 2 to the AntNum field of tag, assigning 3 to the TagType field of tag, and then fill array within the tag with values from 4 to 15.

                    Then within my C# I'm printing all these fields. I can check in such a way that they were transfered correctly from C++.

                    Comment

                    • Suzan YILDIRIM
                      New Member
                      • Jan 2010
                      • 9

                      #11
                      dennisoleksyuk,
                      thanks for your explanation..it 's very clear..i have tried to call my DLL into C# for months..i have seen very miscellaneous examples to marshal the function parameters..but yours is very simple..for example i have done it like

                      Code:
                      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
                            public struct TagIds
                            {
                                public byte TagType;
                                public byte AntNum;
                                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
                                public string Ids; 
                            }
                      
                      public class LibWrap
                      {
                       
                           [DllImport("DrfApiV10.dll", CallingConvention = CallingConvention.StdCall,CharSet=CharSet.Ansi, EntryPoint = "DrfIsoMultiTagIdentify")]
                      
                           public static extern short isoMultiTagIdentify(IntPtr hCom, ref uint Count,[In,Out] TagIds[] value,byte ReaderAddr );
                           public static short isoMultiTagIdentify(IntPtr hCom, ref uint Count, [In,Out] TagIds[] value)
                             {
                                 return isoMultiTagIdentify(hCom,ref Count, value, 0xff);
                             }
                      }
                      what can be said about this..??

                      Comment

                      • dennisoleksyuk
                        New Member
                        • Jan 2010
                        • 17

                        #12
                        Please, give me more specific question.

                        Comment

                        • Suzan YILDIRIM
                          New Member
                          • Jan 2010
                          • 9

                          #13
                          Please, give me more specific question.
                          sorry..it's my foolishness..th e functions that is imported has default values...like unsigned char ReaderAddr = 0xff..for this imported function, i have written an overloaded one..does the compiler give any error??

                          P.S. i haven't tried to communicate the RFID reader yet..before all else i have tried to figure out the DLL

                          Comment

                          • dennisoleksyuk
                            New Member
                            • Jan 2010
                            • 17

                            #14
                            You just remove optional argument from signature in your .NET code.
                            Code:
                            [DllImport("TestDriver.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "?DrfIsoMultiTagIdentify@@YGFKPAIPAUTagIds@@E@Z")]
                                    static extern short DrfIsoMultiTagIdentify(uint hCom, ref int Count, ref TagIds value);
                            C++ library will fill missed arguments with default values.

                            Comment

                            • Suzan YILDIRIM
                              New Member
                              • Jan 2010
                              • 9

                              #15
                              Originally posted by dennisoleksyuk
                              You just remove optional argument from signature in your .NET code.
                              Code:
                              [DllImport("TestDriver.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "?DrfIsoMultiTagIdentify@@YGFKPAIPAUTagIds@@E@Z")]
                                      static extern short DrfIsoMultiTagIdentify(uint hCom, ref int Count, ref TagIds value);
                              C++ library will fill missed arguments with default values.
                              unfortunately default parameters are not supported by C# before 4.0

                              Comment

                              Working...