微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C# 的 C++ DLL 包装器

如何解决C# 的 C++ DLL 包装器

为了能够在 C# 中使用外部 DLL (C++),我正在为它编写包装器。

简单的函数可以工作,但也许可以做得更简单。但是更复杂的回调函数,如 typedef、结构和枚举,它们根本不起作用。

这是*.h文件的一部分:

#pragma once

#if defined(_WIN32)
#if defined(DRFL_EXPORTS)
#define DRFL_API __declspec(dllexport)
#else
#define DRFL_API __declspec(dllimport)
#endif
#endif

#if !defined(DRFL_API)
#define DRFL_API
#endif

#include "DRFS.h"

typedef enum {
    STATE_INITIALIZING,STATE_STANDBY,STATE_MOVING,STATE_SAFE_OFF,STATE_TEACHING,STATE_SAFE_STOP,STATE_EMERGENCY_STOP,STATE_HOMMING,STATE_RECOVERY,STATE_SAFE_STOP2,STATE_SAFE_OFF2,STATE_RESERVED1,STATE_RESERVED2,STATE_RESERVED3,STATE_RESERVED4,STATE_NOT_READY = 15,STATE_LAST,} ROBOT_STATE;

typedef struct _MONITORING_DATA
{
    MONITORING_CONTROL          _tCtrl;
    /* misc. */
    MONITORING_MISC             _tMisc;

} MONITORING_DATA,*LPMONITORING_DATA;

typedef struct _MONITORING_CTRLIO
{
    /* input data */
    READ_CTRLIO_INPUT           _tInput;
    /* output data */
    READ_CTRLIO_OUTPUT          _tOutput;
} MONITORING_CTRLIO,*LPMONITORING_CTRLIO;

typedef struct _MONITORING_MODBUS
{
    /* modbus I/O count */
    unsigned short              _iRegCount;
    /* modbus I/O values */
    MODBUS_REGISTER             _tRegister[MAX_MODBUS_TOTAL_REGISTERS];

} MONITORING_MODBUS,*LPMONITORING_MODBUS;

typedef struct _LOG_ALARM
{
    /* message level */
    unsigned char               _iLevel;
    /* group no */
    unsigned char               _iGroup;
    /* message no */
    unsigned int                _iIndex;
    /* message param */
    char                        _szParam[3][MAX_STRING_SIZE];
} LOG_ALARM,*LPLOG_ALARM;

namespace DRAFramework 
{
    typedef void* LPROBOTCONTROL;

    typedef void (*TOnMonitoringStateCB)(const ROBOT_STATE);
    typedef void (*TOnMonitoringDataCB)(const LPMONITORING_DATA);
    typedef void (*TOnMonitoringCtrlIOCB)(const LPMONITORING_CTRLIO);
    typedef void (*TOnMonitoringModbusCB)(const LPMONITORING_MODBUS);
    typedef void (*TOnLogalarmCB)(LPLOG_ALARM);
    
#ifdef __cplusplus
    extern "C" 
    {
#endif
        ////////////////////////////////////////////////////////////////////////////
        // Instance                                                               //
        ////////////////////////////////////////////////////////////////////////////
        // construct
        DRFL_API LPROBOTCONTROL _CreateRobotControl();
        DRFL_API void _DestroyRobotControl(LPROBOTCONTROL pCtrl);

        // connection
        //for ROS org DRFL_API bool _OpenConnection(LPROBOTCONTROL pCtrl,const char* lpszIpAddr = "192.168.137.100");
        DRFL_API bool _OpenConnection(LPROBOTCONTROL pCtrl,const char* lpszIpAddr = "192.168.137.100",unsigned int usPort = 12345);
        DRFL_API void _CloseConnection(LPROBOTCONTROL pCtrl);

        ////////////////////////////////////////////////////////////////////////////
        // Attributes                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // get verion string
        DRFL_API bool _GetSystemVersion(LPROBOTCONTROL pCtrl,LPSYstem_VERSION pVersion);
        DRFL_API const char* _GetLibraryVersion(LPROBOTCONTROL pCtrl);
        
                
        ////////////////////////////////////////////////////////////////////////////
        //  access control                                                       //
        ////////////////////////////////////////////////////////////////////////////

        // manage access control
        DRFL_API bool _ManageAccessControl(LPROBOTCONTROL pCtrl,MANAGE_ACCESS_CONTROL eAccessControl = MANAGE_ACCESS_CONTROL_REQUEST);
        
        
        ////////////////////////////////////////////////////////////////////////////
        // Callback operation                                                    //
        ////////////////////////////////////////////////////////////////////////////
        DRFL_API void _SetonMonitoringState(LPROBOTCONTROL pCtrl,TOnMonitoringStateCB pCallbackFunc);
        DRFL_API void _SetonMonitoringData(LPROBOTCONTROL pCtrl,TOnMonitoringDataCB pCallbackFunc);   
        DRFL_API void _SetonMonitoringCtrlIO(LPROBOTCONTROL pCtrl,TOnMonitoringCtrlIOCB pCallbackFunc);
        DRFL_API void _SetonMonitoringModbus(LPROBOTCONTROL pCtrl,TOnMonitoringModbusCB pCallbackFunc);
        DRFL_API void _SetonLogalarm(LPROBOTCONTROL pCtrl,TOnLogalarmCB pCallbackFunc);
        
        
        ////////////////////////////////////////////////////////////////////////////
        //  motion Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////
        // basci motion(hold to run)
        DRFL_API bool _Jog(LPROBOTCONTROL pCtrl,JOG_AXIS eJogAxis,MOVE_REFERENCE eMoveReference,float fVeLocity);
        DRFL_API bool _MultiJog(LPROBOTCONTROL pCtrl,float fTargetPos[NUM_TASK],float fVeLocity);
        DRFL_API bool _Home(LPROBOTCONTROL pCtrl,unsigned char bRun);


        ////////////////////////////////////////////////////////////////////////////
        //  GPIO Operations                                                       //
        ////////////////////////////////////////////////////////////////////////////
        // set digital output on flange
        DRFL_API bool _SetToolDigitalOutput(LPROBOTCONTROL pCtrl,GPIO_TOOL_DIGITAL_INDEX eGpioIndex,bool bOnOff);
        // get digital input on flange


        ////////////////////////////////////////////////////////////////////////////
        //  Modbus Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////
        // set modbus register 
        DRFL_API bool _SetModbusValue(LPROBOTCONTROL pCtrl,const char* lpszSymbol,unsigned short nValue);


        ////////////////////////////////////////////////////////////////////////////
        //  Configuration Operations                                               //
        ////////////////////////////////////////////////////////////////////////////
        // set tool(end-effector) information
        DRFL_API bool _SetCurrentTool(LPROBOTCONTROL pCtrl,const char* lpszSymbol);


        ////////////////////////////////////////////////////////////////////////////
        //  drl program Operations                                                //
        ////////////////////////////////////////////////////////////////////////////
        // program start
        DRFL_API bool _PlayDrlStart(LPROBOTCONTROL pCtrl,ROBOT_SYstem eRobotSystem,const char* lpszDrlProgram);

        void PrintFParam(float* printArr,int iSize,string strFunc);
        void PrintUCParam(unsigned char* printArr,string strFunc);
#ifdef __cplusplus
    };
#endif

#ifdef __cplusplus
    class CDRFL
    {
    public:
        ////////////////////////////////////////////////////////////////////////////
        // Connection                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // construct
        CDRFL() { _rbtCtrl = _CreateRobotControl(); }
        virtual ~CDRFL() { _DestroyRobotControl(_rbtCtrl);   }

        // connection
        //for ROS org bool OpenConnection(string strIpAddr = "192.168.137.100") { return _OpenConnection(_rbtCtrl,strIpAddr.c_str()); };
        bool OpenConnection(string strIpAddr = "192.168.137.100",unsigned int usPort= 12345) { return _OpenConnection(_rbtCtrl,strIpAddr.c_str(),usPort); };
        void CloseConnection() { _CloseConnection(_rbtCtrl); }


        ////////////////////////////////////////////////////////////////////////////
        // Callback operation                                                    //
        ////////////////////////////////////////////////////////////////////////////
        // robot status data
        void SetonMonitoringState(TOnMonitoringStateCB pCallbackFunc) { _SetonMonitoringState(_rbtCtrl,pCallbackFunc); };
        // robot operating data
        void SetonMonitoringData(TOnMonitoringDataCB pCallbackFunc) { _SetonMonitoringData(_rbtCtrl,pCallbackFunc); };
        // ctrl-Box I/O data
        void SetonMonitoringCtrlIO(TOnMonitoringCtrlIOCB pCallbackFunc) { _SetonMonitoringCtrlIO(_rbtCtrl,pCallbackFunc); };
        // modbus I/O data
        void SetonMonitoringModbus(TOnMonitoringModbusCB pCallbackFunc) { _SetonMonitoringModbus(_rbtCtrl,pCallbackFunc); };
        // robot speed mode event
        void SetonMonitoringSpeedMode(TOnMonitoringSpeedModeCB pCallbackFunc) { _SetonMonitoringSpeedMode(_rbtCtrl,pCallbackFunc); };
        // robot access control event
        void SetonMonitoringAccessControl(TOnMonitoringAccessControlCB pCallbackFunc) { _SetonMonitoringAccessControl(_rbtCtrl,pCallbackFunc); };
        // roobt alaram data
        void SetonLogalarm(TOnLogalarmCB pCallbackFunc)  { _SetonLogalarm(_rbtCtrl,pCallbackFunc); };
        // robot homing completed event
        void SetonHommingCompleted(TOnHommingCompletedCB pCallbackFunc) { _SetonHommingCompleted(_rbtCtrl,pCallbackFunc); };
        // Tp Initailzing completed
        void SetonTpInitializingCompleted(TOnTpInitializingCompletedCB pCallbackFunc) { _SetonTpInitializingCompleted(_rbtCtrl,pCallbackFunc); };
        // robot mastering needed event
        void SetonMasteringNeed(TOnMasteringNeedCB pCallbackFunc) { _SetonMasteringNeed(_rbtCtrl,pCallbackFunc); };
        // program stopeed event
        void SetonProgramStopped(TOnProgramStoppedCB pCallbackFunc) { _SetonProgramStopped(_rbtCtrl,pCallbackFunc); };
        // robot disconneted event
        void Setondisconnected(TOndisconnectedCB pCallbackFunc) { _Setondisconnected(_rbtCtrl,pCallbackFunc); };


        ////////////////////////////////////////////////////////////////////////////
        // Attributes                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // get verion string
        bool GetSystemVersion(LPSYstem_VERSION pVersion) { return _GetSystemVersion(_rbtCtrl,pVersion); };
        const char* GetLibraryVersion() { return _GetLibraryVersion(_rbtCtrl); };


        ////////////////////////////////////////////////////////////////////////////
        //  access control                                                        //
        ////////////////////////////////////////////////////////////////////////////

        // manage access control
        bool ManageAccessControl(MANAGE_ACCESS_CONTROL eAccessControl = MANAGE_ACCESS_CONTROL_REQUEST) { return _ManageAccessControl(_rbtCtrl,eAccessControl); };
        
        
        ////////////////////////////////////////////////////////////////////////////
        //  motion Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////
        // basic control(hold to run)
        bool Jog(JOG_AXIS eJogAxis,float fVeLocity) { return _Jog(_rbtCtrl,eJogAxis,eMoveReference,fVeLocity); };
        bool MultiJog(float fTargetPos[NUM_TASK],float fVeLocity) { return _MultiJog(_rbtCtrl,fTargetPos,fVeLocity); };
       
       
        ////////////////////////////////////////////////////////////////////////////
        //  GPIO Operations                                                       //
        ////////////////////////////////////////////////////////////////////////////
        // set digital output on flange
        bool SetToolDigitalOutput(GPIO_TOOL_DIGITAL_INDEX eGpioIndex,bool bOnOff) { return _SetToolDigitalOutput(_rbtCtrl,eGpioIndex,bOnOff); };


        ////////////////////////////////////////////////////////////////////////////
        //  Modbus Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////
        // set modbus register
        bool SetModbusValue(string strSymbol,unsigned short nValue) { return _SetModbusValue(_rbtCtrl,strSymbol.c_str(),nValue); };


        ////////////////////////////////////////////////////////////////////////////
        //  Configuration Operations                                               //
        ////////////////////////////////////////////////////////////////////////////
        // set tool(end-effector) information
        bool SetCurrentTool(string strSymbol) { return _SetCurrentTool(_rbtCtrl,strSymbol.c_str()); };

        
        ////////////////////////////////////////////////////////////////////////////
        //  drl program Operations                                                //
        ////////////////////////////////////////////////////////////////////////////
        //program start
        bool PlayDrlStart(ROBOT_SYstem eRobotSystem,string strDrlProgram) { return _PlayDrlStart(_rbtCtrl,eRobotSystem,strDrlProgram.c_str()); };

protected:
        LPROBOTCONTROL _rbtCtrl;
    };
#endif
}

这是我目前构建包装器的部分:

using System;
using System.Runtime.InteropServices;

namespace CDRFL_Wrapper
{
    public enum RobotState
    {
        STATE_INITIALIZING,};
    
    public struct SystemVersion
    {
        /* smarttp version */
        //char _szSmartTp[MAX_SYMBOL_SIZE];
        public char _szSmartTp;

        /* controller version */
        public char _szController;
        //char _szController[MAX_SYMBOL_SIZE];

        /* interpreter version */
        public char _szInterpreter;
        //char _szInterpreter[MAX_SYMBOL_SIZE];

        /* inverter version */
        public char _szInverter;
        //char _szInverter[MAX_SYMBOL_SIZE];

        /* SafetyBoard version */
        public char _szSafetyBoard;
        //char _szSafetyBoard[MAX_SYMBOL_SIZE];

        /* robot serial number */
        public char _szRobotSerial;
        //char _szRobotSerial[MAX_SYMBOL_SIZE];

        /* robot model number*/
        public char _szRobotModel;
        //char _szRobotModel[MAX_SYMBOL_SIZE];

        /* jts board version */
        public char _szJTSBoard;
        //char _szJTSBoard[MAX_SYMBOL_SIZE];

        /* flange board version */
        public char _szFlangeBoard;
        //char _szFlangeBoard[MAX_SYMBOL_SIZE];
    }
    
    public partial class CDRFL_CSharp
    {
        // Variables
        private readonly IntPtr ptrRobotControl;

        public delegate void TOnMonitoringStateCB(RobotState value);


        ////////////////////////////////////////////////////////////////////////////
        // Instance                                                               //
        ////////////////////////////////////////////////////////////////////////////
        // construct
        [DllImport(@"DLL.dll",EntryPoint = "_CreateRobotControl")]
        private static extern IntPtr _CreateRobotControl();
        [DllImport(@"DLL.dll",EntryPoint = "_DestroyRobotControl")]
        private static extern IntPtr _DestroyRobotControl(IntPtr robotControlPointer);

        // connection
        //for ROS org DRFL_API bool _OpenConnection(LPROBOTCONTROL pCtrl,const char* lpszIpAddr = "192.168.137.100");
        [DllImport(@"DLL",EntryPoint = "_OpenConnection")]
        private static extern bool _OpenConnection(IntPtr robotControlPointer,string ipAddr,uint port);
        [DllImport(@"DLL.dll",EntryPoint = "_CloseConnection")]
        private static extern bool _CloseConnection(IntPtr robotControlPointer);


        ////////////////////////////////////////////////////////////////////////////
        // Attributes                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // get verion string
        [DllImport(@"DLL.dll",EntryPoint = "_GetSystemVersion")]
        private static extern SystemVersion _GetSystemVersion(IntPtr robotControlPointer);
        [DllImport(@"DLL.dll",EntryPoint = "_GetLibraryVersion")]
        private static extern char[] _GetLibraryVersion(IntPtr robotControlPointer);

        
                
        ////////////////////////////////////////////////////////////////////////////
        //  access control                                                       //
        ////////////////////////////////////////////////////////////////////////////

        // manage access control
        DRFL_API bool _ManageAccessControl(LPROBOTCONTROL pCtrl,MANAGE_ACCESS_CONTROL eAccessControl = MANAGE_ACCESS_CONTROL_REQUEST);
        
        
        ////////////////////////////////////////////////////////////////////////////
        // Callback operation                                                    //
        ////////////////////////////////////////////////////////////////////////////
        //[DllImport(@"DLL.dll",EntryPoint = "_SetonMonitoringState")]
        //public static extern void _SetonMonitoringState(IntPtr robotControlPointer,TOnMonitoringStateCB callbackFunction);
        
        ////////////////////////////////////////////////////////////////////////////
        //  motion Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////
        //  GPIO Operations                                                       //
        ////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////
        //  Modbus Operations                                                     //
        ////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////
        //  Configuration Operations                                               //
        ////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////
        //  drl program Operations                                                //
        ////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////
        // Connection                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // construct
        // CDRFL() { _rbtCtrl = _CreateRobotControl(); }
        public CDRFL_CSharp() { ptrRobotControl = _CreateRobotControl(); }
        // virtual ~CDRFL() { _DestroyRobotControl(_rbtCtrl);   }
        ~CDRFL_CSharp() { _DestroyRobotControl(ptrRobotControl); }

        // connection
        // for ROS org bool OpenConnection(string strIpAddr = "192.168.137.100") { return _OpenConnection(_rbtCtrl,strIpAddr.c_str()); };
        // bool OpenConnection(string strIpAddr = "192.168.137.100",usPort); };
        public bool OpenConnection(string IpAddr = "192.168.137.50",uint Port = 12345) { return _OpenConnection(ptrRobotControl,IpAddr,Port); }
        // void CloseConnection() { _CloseConnection(_rbtCtrl); }
        public bool CloseConnection() { return _CloseConnection(ptrRobotControl); }


        ////////////////////////////////////////////////////////////////////////////
        // Callback operation                                                    //
        ////////////////////////////////////////////////////////////////////////////
        // robot status data
        // void SetonMonitoringState(TOnMonitoringStateCB pCallbackFunc) { _SetonMonitoringState(_rbtCtrl,pCallbackFunc); };
        public void SetonMonitoringState(TOnMonitoringStateCB pCallbackFunc) { _SetonMonitoringState(ptrRobotControl,pCallbackFunc); }



        ////////////////////////////////////////////////////////////////////////////
        // Attributes                                                             //
        ////////////////////////////////////////////////////////////////////////////
        // get verion string
        // bool GetSystemVersion(LPSYstem_VERSION pVersion) { return _GetSystemVersion(_rbtCtrl,pVersion); };
        public SystemVersion GetSystemVersion() { return _GetSystemVersion(ptrRobotControl); }
        // const char* GetLibraryVersion() { return _GetLibraryVersion(_rbtCtrl); };
        public string GetLibraryVersion() { return new string(_GetLibraryVersion(ptrRobotControl)); }

  
    }
}

这是调用代码

...

CDRFL_CSharp Drfl = new CDRFL_CSharp();

// Connect to Robot
bool bConnected = Drfl.OpenConnection(IP);

if (bConnected)
{
    // Get Robot information
    CDRFL_Wrapper.SystemVersion RonoterSystemVersion = Drfl.GetSystemVersion();
    string RoboterLibraryVersion = Drfl.GetLibraryVersion();

    Console.WriteLine("System Version - Controller: " + RonoterSystemVersion._szController);
    Console.WriteLine("System Version - Flang Board: " + RonoterSystemVersion._szFlangeBoard);
    Console.WriteLine("System Version - Robot Model: " + RonoterSystemVersion._szRobotModel);
    Console.WriteLine("System Version - Robot Serial: " + RonoterSystemVersion._szRobotSerial);
    Console.WriteLine("Libray Version: " + RoboterLibraryVersion);

    TOnMonitoringStateCB myDelegate = new TOnMonitoringStateCB(OnMonitoringStateCB);
    Drfl.SetonMonitoringState(myDelegate);
}

...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。