创建博客 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

程序员驿站

淘宝店:http://shop106888457.taobao.com

 
 
 

日志

 
 

C#调用C++写的dll,包含结构体转换和C#动态调用dll  

2008-11-12 11:15:32|  分类: 编程小知识 |  标签: |举报 |字号 订阅

这段时间用C++给客户做了一个通讯的dll。但客户是用C#的,所以研究了下C#,把C++的头文件,改写成C#的。主要是转换了结构体的定义,dll函数的调用,C#中的dll的动态调用,C++和C#之间的时间变量的传递。现在和大家分享一下。

C++的头文件:

#pragma once

//

//设置

//

typedef struct _RMusterSettings

{

   DWORD dwDataSize;

   RComm Comm;

   RCoData CoData;

   double RealClock;

   WORD MeterCount;

   WORD RecNoMax;

   struct _RAutoReadSettings

   {

       BYTE Enable;

       BYTE Days[31];

       struct _RARTime

       {

           BYTE Enable;

           BYTE Hour;

           BYTE Min;

           BYTE Sec;

      

       }Time[24];

   } RAutoReadSettings;

} RMusterSettings;

//

//通讯类定义

//

typedef HANDLE (*CREATEXXXXCOMM)();

typedef INT (*FREEXXXXCOMM)(HANDLE);

typedef INT (*XXXXCOMM)(HANDLE,WORD,void *);

typedef INT (*XXXXABORT)(HANDLE);

class CXXXXComm

{

private:

   HINSTANCE           hLib;

   HANDLE               hXXXXComm;

   CREATEXXXXCOMM       fnCreateXXXXComm;

   FREEXXXXCOMM       fnFreeXXXXComm;

   XXXXCOMM           fnXXXXComm;

   XXXXABORT            fnXXXXAbort;

public:

   CXXXXComm(PCHAR fileName)

   {

       hLib = LoadLibrary(fileName);

       if (hLib != NULL)

       {

           fnCreateXXXXComm   = (CREATEXXXXCOMM) GetProcAddress(hLib, "CreateXXXXComm");

           fnFreeXXXXComm      = (FREEXXXXCOMM) GetProcAddress(hLib, "FreeXXXXComm");

           fnXXXXComm          = (XXXXCOMM) GetProcAddress(hLib, "XXXXComm");

           fnXXXXAbort       = (XXXXABORT) GetProcAddress(hLib, "XXXXAbort");

           hXXXXComm           = fnCreateXXXXComm();

       }

   };

   ~CXXXXComm()

   {

       if (hLib != NULL)

       {

           fnFreeXXXXComm(hXXXXComm);

           FreeLibrary(hLib);

       }

   };

   INT Comm(WORD cmd, void * data)

   {

       if (hLib != NULL)

           return fnXXXXComm(hXXXXComm,cmd,data);

       else

           return EC_DLL_NOT_FOUND;

   };

   INT Abort()

   {

       if (hLib != NULL)

           return fnXXXXAbort(hXXXXComm);

       else

           return 0;

   };

};

C#的类文件

using System;

using System.Runtime.InteropServices;

namespace Flagele.rd.CXXXXComm

{

    //

    //设置

    //

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public struct RARTime

    {

        public byte Enable;

        public byte Hour;

        public byte Min;

        public byte Sec;

    }       

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public struct RAutoReadSettings

    {

      

        public byte     Enable;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]

        public byte[]   Days;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]

        public RARTime[] Time;

    }       

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public class RMusterSettings

    {

        public uint     dwDataSize;

        public RComm    Comm;

        public RCoData CoData;

        //

        public long     RealClock;

        public ushort   MeterCount;

        public ushort   RecNoMax;

        public RAutoReadSettings ARSettings;

    }

     //

    //通讯类

    //

    public class CXXXXComm

    {

        private uint hLib;

        private uint hXXXXComm;

        private delegate uint CREATEXXXXCOMM();

        private delegate uint FREEXXXXCOMM(uint hFe);

        private delegate uint XXXXCOMM(uint hFe, ushort cmd, [In,Out,MarshalAs(UnmanagedType.AsAny)] Object data);

        private delegate uint XXXXABORT(uint hFe);

        private CREATEXXXXCOMM fnCreateXXXXComm;

        private FREEXXXXCOMM fnFreeXXXXComm;

        private XXXXCOMM fnXXXXComm;

        private XXXXABORT fnXXXXAbort;

        [DllImport("Kernel32")]

        private static extern uint GetProcAddress(uint handle, String funcname);

        [DllImport("Kernel32")]

        private static extern uint LoadLibrary(String funcname);

        [DllImport("Kernel32")]

        private static extern uint FreeLibrary(uint handle);

        private static Delegate GetAddress(uint dllModule, string functionname, Type t)

        {

            uint addr = GetProcAddress(dllModule, functionname);

            if (addr == 0)

                return null;

            else

                return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);

        }

        public CXXXXComm()

        {

            hLib = LoadLibrary("XXXXComm.dll");

            if (hLib != 0)

            {

                fnCreateXXXXComm = (CREATEXXXXCOMM)GetAddress(hLib, "CreateXXXXComm", typeof(CREATEXXXXCOMM));

                fnFreeXXXXComm = (FREEXXXXCOMM)GetAddress(hLib, "FreeXXXXComm", typeof(FREEXXXXCOMM));

                fnXXXXComm = (XXXXCOMM)GetAddress(hLib, "XXXXComm", typeof(XXXXCOMM));

                fnXXXXAbort = (XXXXABORT)GetAddress(hLib, "XXXXAbort", typeof(XXXXABORT));

                if (fnCreateXXXXComm != null)

                {

                    hXXXXComm = fnCreateXXXXComm();

                }

            }

        }

        ~CXXXXComm()

        {

            if (fnFreeXXXXComm != null)

            {

                fnFreeXXXXComm(hXXXXComm);

            }

            if (hLib != 0)

            {

                FreeLibrary(hLib);

            }

        }

        public uint comm(ushort cmd, [MarshalAs(UnmanagedType.AsAny)] Object data)

        {

            if (hLib != 0)

            {

                return fnXXXXComm(hXXXXComm, cmd, data);

            }

            else

                return CFeError.EC_DLL_NOT_FOUND;

        }

        public uint abort()

        {

            if (hLib != 0)

            {

                return fnXXXXAbort(hXXXXComm);

            }

            else

                return 0;

        }

    }

}

C#的调用例子

//事先要创建XXXXComm

//private CXXXXComm XXXXComm;

//public Form1()

//{

//    InitializeComponent();

//    XXXXComm= new CXXXXComm();

//}

//

//▼写设置

//

         mustersettings.ARSettings.Enable = 1;

         for (i = 0; i < 31; i++)

         mustersettings.ARSettings.Days[i] = 1;

         for (i = 0; i < 24; i++)

         {

                  mustersettings.ARSettings.Time[i].Enable = 0;

                  mustersettings.ARSettings.Time[i].Hour = (byte)i;

                  mustersettings.ARSettings.Time[i].Min = 0;

                  mustersettings.ARSettings.Time[i].Sec = 0;

         }

         Rec = XXXXComm.comm(CFeCmd.W_MusterAutoRead,(Object)mustersettings);

         if (Rec == 0)

         {

                  //成功

         }

  评论这张
 
阅读(1006)| 评论(0)
推荐 转载

历史上的今天

最近读者

热度

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2014