如何解决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 举报,一经查实,本站将立刻删除。