C#调用C++写的dll,包含结构体转换和C#动态调用dll(头文件转换为类)

14 篇文章 0 订阅
C#调用C++写的dll,包含结构体转换和C#动态调用dll
2008年08月19日 星期二 17:13
这段时间用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)
         {
                  //成功
         }

 

文献来源:http://hi.baidu.com/flagwes/blog/item/e56aad106cb46607203f2e73.html

 

 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值